mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 10:45:24 +00:00
- Implement SetupCopyOEMInfW
- Correctly sort drivers by rank and by date - Fix memory corruption if %SYSTEMROOT% was longer than 128 chars svn path=/trunk/; revision=22109
This commit is contained in:
parent
d599ad5c78
commit
05875a2c6d
|
@ -5486,14 +5486,15 @@ AddDriverToList(
|
|||
driverInfo->Details.InfFileName[MAX_PATH - 1] = '\0';
|
||||
|
||||
/* Fill InfDate field */
|
||||
/* FIXME: hFile = CreateFile(driverInfo->Details.InfFileName,
|
||||
hFile = CreateFile(
|
||||
InfFile,
|
||||
GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
Result = GetFileTime(hFile, NULL, NULL, &driverInfo->Details.InfDate);
|
||||
if (!Result)
|
||||
goto cleanup;*/
|
||||
goto cleanup;
|
||||
|
||||
/* Fill SectionName field */
|
||||
Result = SetupGetStringFieldW(
|
||||
|
@ -5576,10 +5577,10 @@ AddDriverToList(
|
|||
struct DriverInfoElement *CurrentDriver;
|
||||
CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
|
||||
if (CurrentDriver->DriverRank > Rank ||
|
||||
(CurrentDriver->DriverRank == Rank && CurrentDriver->DriverDate.QuadPart > driverInfo->DriverDate.QuadPart))
|
||||
(CurrentDriver->DriverRank == Rank && CurrentDriver->DriverDate.QuadPart < driverInfo->DriverDate.QuadPart))
|
||||
{
|
||||
/* Insert before the current item */
|
||||
InsertHeadList(PreviousEntry, &driverInfo->ListEntry);
|
||||
InsertHeadList(PreviousEntry->Blink, &driverInfo->ListEntry);
|
||||
break;
|
||||
}
|
||||
PreviousEntry = PreviousEntry->Flink;
|
||||
|
@ -5858,17 +5859,14 @@ done:
|
|||
|
||||
static struct InfFileDetails *
|
||||
CreateInfFileDetails(
|
||||
IN LPCWSTR InfFileName)
|
||||
IN LPCWSTR FullInfFileName)
|
||||
{
|
||||
struct InfFileDetails *details;
|
||||
PWCHAR last;
|
||||
DWORD Needed;
|
||||
|
||||
last = strrchrW(InfFileName, '\\');
|
||||
Needed = FIELD_OFFSET(struct InfFileDetails, szData)
|
||||
+ strlenW(InfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
if (last != NULL)
|
||||
Needed += (last - InfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
+ strlenW(FullInfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
|
||||
details = HeapAlloc(GetProcessHeap(), 0, Needed);
|
||||
if (!details)
|
||||
|
@ -5878,17 +5876,18 @@ CreateInfFileDetails(
|
|||
}
|
||||
|
||||
memset(details, 0, Needed);
|
||||
strcpyW(details->szData, FullInfFileName);
|
||||
last = strrchrW(details->szData, '\\');
|
||||
if (last)
|
||||
{
|
||||
details->DirectoryName = details->szData;
|
||||
details->FullInfFileName = &details->szData[last - InfFileName + 1];
|
||||
strncpyW(details->DirectoryName, InfFileName, last - InfFileName);
|
||||
details->FileName = last + 1;
|
||||
*last = '\0';
|
||||
}
|
||||
else
|
||||
details->FullInfFileName = details->szData;
|
||||
strcpyW(details->FullInfFileName, InfFileName);
|
||||
details->FileName = details->szData;
|
||||
ReferenceInfFile(details);
|
||||
details->hInf = SetupOpenInfFileW(InfFileName, NULL, INF_STYLE_WIN4, NULL);
|
||||
details->hInf = SetupOpenInfFileW(FullInfFileName, NULL, INF_STYLE_WIN4, NULL);
|
||||
if (details->hInf == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, details);
|
||||
|
@ -6022,20 +6021,13 @@ SetupDiBuildDriverInfoList(
|
|||
LPCWSTR filename;
|
||||
LPWSTR pFullFilename;
|
||||
|
||||
if (InstallParams.Flags & DI_ENUMSINGLEINF)
|
||||
{
|
||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
|
||||
if (!FullInfFileName)
|
||||
goto done;
|
||||
pFullFilename = &FullInfFileName[0];
|
||||
}
|
||||
else if (*InstallParams.DriverPath)
|
||||
if (!(InstallParams.Flags & DI_ENUMSINGLEINF) && *InstallParams.DriverPath)
|
||||
{
|
||||
DWORD len;
|
||||
len = GetFullPathNameW(InstallParams.DriverPath, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto done;
|
||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, len + MAX_PATH);
|
||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, (len + 1 + MAX_PATH) * sizeof(WCHAR));
|
||||
if (!FullInfFileName)
|
||||
goto done;
|
||||
len = GetFullPathNameW(InstallParams.DriverPath, len, FullInfFileName, NULL);
|
||||
|
@ -6047,7 +6039,7 @@ SetupDiBuildDriverInfoList(
|
|||
}
|
||||
else
|
||||
{
|
||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
|
||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
|
||||
if (!FullInfFileName)
|
||||
goto done;
|
||||
pFullFilename = &FullInfFileName[0];
|
||||
|
@ -8048,7 +8040,7 @@ SetupDiInstallDevice(
|
|||
pSectionName = &SectionName[strlenW(SectionName)];
|
||||
|
||||
/* Get information from [Version] section */
|
||||
if (!SetupDiGetINFClassW(SelectedDriver->InfFileDetails->FullInfFileName, &ClassGuid, ClassName, MAX_CLASS_NAME_LEN, &RequiredSize))
|
||||
if (!SetupDiGetINFClassW(SelectedDriver->Details.InfFileName, &ClassGuid, ClassName, MAX_CLASS_NAME_LEN, &RequiredSize))
|
||||
goto cleanup;
|
||||
/* Format ClassGuid to a string */
|
||||
if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
|
||||
|
@ -8065,6 +8057,35 @@ SetupDiInstallDevice(
|
|||
lpFullGuidString[RequiredSize + 1] = '}';
|
||||
lpFullGuidString[RequiredSize + 2] = '\0';
|
||||
|
||||
/* Copy .inf file to Inf\ directory (if needed) */
|
||||
Result = InfIsFromOEMLocation(SelectedDriver->Details.InfFileName, &NeedtoCopyFile);
|
||||
if (!Result)
|
||||
goto cleanup;
|
||||
if (NeedtoCopyFile)
|
||||
{
|
||||
WCHAR NewFileName[MAX_PATH];
|
||||
struct InfFileDetails *newInfFileDetails;
|
||||
Result = SetupCopyOEMInfW(
|
||||
SelectedDriver->Details.InfFileName,
|
||||
NULL,
|
||||
SPOST_NONE,
|
||||
SP_COPY_NOOVERWRITE,
|
||||
NewFileName, MAX_PATH,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!Result)
|
||||
goto cleanup;
|
||||
/* Create a new struct InfFileDetails, and set it to
|
||||
* SelectedDriver->InfFileDetails, to release use of
|
||||
* current InfFile */
|
||||
newInfFileDetails = CreateInfFileDetails(NewFileName);
|
||||
if (!newInfFileDetails)
|
||||
goto cleanup;
|
||||
DereferenceInfFile(SelectedDriver->InfFileDetails);
|
||||
SelectedDriver->InfFileDetails = newInfFileDetails;
|
||||
strcpyW(SelectedDriver->Details.InfFileName, NewFileName);
|
||||
}
|
||||
|
||||
/* Open/Create driver key information */
|
||||
#if _WIN32_WINNT >= 0x502
|
||||
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
|
||||
|
@ -8105,7 +8126,7 @@ SetupDiInstallDevice(
|
|||
TRACE("DriverDate : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
|
||||
TRACE("DriverDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
|
||||
TRACE("DriverVersion : '%u.%u.%u.%u'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
|
||||
TRACE("InfPath : '%s'\n", debugstr_w(SelectedDriver->Details.InfFileName));
|
||||
TRACE("InfPath : '%s'\n", debugstr_w(SelectedDriver->InfFileDetails->FileName));
|
||||
TRACE("InfSection : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName));
|
||||
TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
|
||||
TRACE("MatchingDeviceId: '%s'\n", debugstr_w(SelectedDriver->MatchingId));
|
||||
|
@ -8122,7 +8143,7 @@ SetupDiInstallDevice(
|
|||
rc = RegSetValueEx(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
|
||||
}
|
||||
if (rc == ERROR_SUCCESS)
|
||||
rc = RegSetValueEx(hKey, REGSTR_VAL_INFPATH, 0, REG_SZ, (const BYTE *)SelectedDriver->Details.InfFileName, (strlenW(SelectedDriver->Details.InfFileName) + 1) * sizeof(WCHAR));
|
||||
rc = RegSetValueEx(hKey, REGSTR_VAL_INFPATH, 0, REG_SZ, (const BYTE *)SelectedDriver->InfFileDetails->FileName, (strlenW(SelectedDriver->InfFileDetails->FileName) + 1) * sizeof(WCHAR));
|
||||
if (rc == ERROR_SUCCESS)
|
||||
rc = RegSetValueEx(hKey, REGSTR_VAL_INFSECTION, 0, REG_SZ, (const BYTE *)SelectedDriver->Details.SectionName, (strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
|
||||
if (rc == ERROR_SUCCESS)
|
||||
|
@ -8156,26 +8177,6 @@ SetupDiInstallDevice(
|
|||
if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
|
||||
RebootRequired = TRUE;
|
||||
|
||||
/* Copy .inf file to Inf\ directory (if needed) */
|
||||
Result = InfIsFromOEMLocation(SelectedDriver->InfFileDetails->FullInfFileName, &NeedtoCopyFile);
|
||||
if (!Result)
|
||||
goto cleanup;
|
||||
if (NeedtoCopyFile)
|
||||
{
|
||||
Result = SetupCopyOEMInfW(
|
||||
SelectedDriver->InfFileDetails->FullInfFileName,
|
||||
NULL,
|
||||
SPOST_NONE,
|
||||
SP_COPY_NOOVERWRITE,
|
||||
NULL, 0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!Result)
|
||||
goto cleanup;
|
||||
/* FIXME: create a new struct InfFileDetails, and set it to SelectedDriver->InfFileDetails,
|
||||
* to release use of current InfFile */
|
||||
}
|
||||
|
||||
/* Open device registry key */
|
||||
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
|
||||
if (hKey == INVALID_HANDLE_VALUE)
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
|
||||
|
||||
/* Unicode constants */
|
||||
static const WCHAR BackSlash[] = {'\\',0};
|
||||
static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
|
||||
|
||||
/* info passed to callback functions dealing with files */
|
||||
struct files_callback_info
|
||||
{
|
||||
|
@ -1661,3 +1665,157 @@ cleanup:
|
|||
TRACE("Returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupCopyOEMInfW (SETUPAPI.@)
|
||||
*/
|
||||
BOOL WINAPI SetupCopyOEMInfW(
|
||||
IN PCWSTR SourceInfFileName,
|
||||
IN PCWSTR OEMSourceMediaLocation,
|
||||
IN DWORD OEMSourceMediaType,
|
||||
IN DWORD CopyStyle,
|
||||
OUT PWSTR DestinationInfFileName OPTIONAL,
|
||||
IN DWORD DestinationInfFileNameSize,
|
||||
OUT PDWORD RequiredSize OPTIONAL,
|
||||
OUT PWSTR* DestinationInfFileNameComponent OPTIONAL)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
|
||||
debugstr_w(SourceInfFileName), debugstr_w(OEMSourceMediaLocation), OEMSourceMediaType,
|
||||
CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
|
||||
RequiredSize, DestinationInfFileNameComponent);
|
||||
|
||||
if (!SourceInfFileName)
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
else if (OEMSourceMediaType != SPOST_NONE && OEMSourceMediaType != SPOST_PATH && OEMSourceMediaType != SPOST_URL)
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
else if (CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY))
|
||||
{
|
||||
TRACE("Unknown flags: 0x%08lx\n", CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY));
|
||||
SetLastError(ERROR_INVALID_FLAGS);
|
||||
}
|
||||
else if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
else if (CopyStyle & SP_COPY_OEMINF_CATALOG_ONLY)
|
||||
{
|
||||
FIXME("CopyStyle 0x%lx not supported\n", SP_COPY_OEMINF_CATALOG_ONLY);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE hSearch = INVALID_HANDLE_VALUE;
|
||||
WIN32_FIND_DATAW FindFileData;
|
||||
BOOL AlreadyExists;
|
||||
DWORD NextFreeNumber = 0;
|
||||
SIZE_T len;
|
||||
LPWSTR pFullFileName = NULL;
|
||||
LPWSTR pFileName; /* Pointer into pFullFileName buffer */
|
||||
|
||||
if (OEMSourceMediaType == SPOST_PATH || OEMSourceMediaType == SPOST_URL)
|
||||
FIXME("OEMSourceMediaType 0x%lx ignored\n", OEMSourceMediaType);
|
||||
|
||||
/* Search if the specified .inf file already exists in %WINDIR%\Inf */
|
||||
AlreadyExists = FALSE; /* FIXME */
|
||||
|
||||
if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY)
|
||||
{
|
||||
/* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
goto cleanup;
|
||||
}
|
||||
else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE))
|
||||
{
|
||||
//SetLastError(ERROR_FILE_EXISTS);
|
||||
/* FIXME: set return fields */
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
FIXME("File already exists. Need to return its name!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Search the number to give to OEM??.INF */
|
||||
len = MAX_PATH + 1 + strlenW(InfDirectory) + 13;
|
||||
pFullFileName = MyMalloc(len * sizeof(WCHAR));
|
||||
if (!pFullFileName)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
len = GetSystemWindowsDirectoryW(pFullFileName, MAX_PATH);
|
||||
if (len == 0 || len > MAX_PATH)
|
||||
goto cleanup;
|
||||
if (pFullFileName[strlenW(pFullFileName) - 1] != '\\')
|
||||
strcatW(pFullFileName, BackSlash);
|
||||
strcatW(pFullFileName, InfDirectory);
|
||||
pFileName = &pFullFileName[strlenW(pFullFileName)];
|
||||
sprintfW(pFileName, L"oem*.inf", NextFreeNumber);
|
||||
hSearch = FindFirstFileW(pFullFileName, &FindFileData);
|
||||
if (hSearch == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
DWORD CurrentNumber;
|
||||
if (swscanf(FindFileData.cFileName, L"oem%lu.inf", &CurrentNumber) == 1
|
||||
&& CurrentNumber <= 99999)
|
||||
{
|
||||
NextFreeNumber = CurrentNumber + 1;
|
||||
}
|
||||
} while (FindNextFile(hSearch, &FindFileData));
|
||||
}
|
||||
|
||||
if (NextFreeNumber > 99999)
|
||||
{
|
||||
ERR("Too much custom .inf files\n");
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create the full path: %WINDIR%\Inf\OEM{XXXXX}.inf */
|
||||
sprintfW(pFileName, L"oem%lu.inf", NextFreeNumber);
|
||||
TRACE("Next available file is %s\n", debugstr_w(pFileName));
|
||||
|
||||
if (RequiredSize)
|
||||
*RequiredSize = len;
|
||||
if (DestinationInfFileName)
|
||||
{
|
||||
if (DestinationInfFileNameSize < len)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
goto cleanup;
|
||||
}
|
||||
strcpyW(DestinationInfFileName, pFullFileName);
|
||||
if (DestinationInfFileNameComponent)
|
||||
*DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName];
|
||||
}
|
||||
|
||||
if (!CopyFileW(SourceInfFileName, pFullFileName, TRUE))
|
||||
{
|
||||
TRACE("CopyFileW() failed with error 0x%lx\n", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (CopyStyle & SP_COPY_DELETESOURCE)
|
||||
{
|
||||
if (!DeleteFileW(SourceInfFileName))
|
||||
{
|
||||
TRACE("DeleteFileW() failed with error 0x%lx\n", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
cleanup:
|
||||
if (hSearch != INVALID_HANDLE_VALUE)
|
||||
FindClose(hSearch);
|
||||
MyFree(pFullFileName);
|
||||
}
|
||||
|
||||
TRACE("Returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -78,10 +78,9 @@ struct InfFileDetails
|
|||
* be NULL if the file is already in %SYSTEMROOT%\Inf.
|
||||
* Points into szData at then end of the structure */
|
||||
PCWSTR DirectoryName;
|
||||
/* Contains the full file name of the .inf file. However, the directory
|
||||
* part may be missing if the file is already in %SYSTEMROOT%\Inf.
|
||||
/* Contains the .inf file name (without directory name).
|
||||
* Points into szData at then end of the structure */
|
||||
PCWSTR FullInfFileName;
|
||||
PCWSTR FileName;
|
||||
|
||||
WCHAR szData[ANYSIZE_ARRAY];
|
||||
};
|
||||
|
|
|
@ -50,21 +50,6 @@ BOOL WINAPI SetupDiGetDeviceInfoListDetailA(HDEVINFO devinfo, PSP_DEVINFO_LIST_D
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupCopyOEMInfW (SETUPAPI.@)
|
||||
*/
|
||||
BOOL WINAPI SetupCopyOEMInfW(PCWSTR sourceinffile, PCWSTR sourcemedialoc,
|
||||
DWORD mediatype, DWORD copystyle, PWSTR destinfname,
|
||||
DWORD destnamesize, PDWORD required,
|
||||
PWSTR *destinfnamecomponent)
|
||||
{
|
||||
FIXME("%s %s 0x%lx 0x%lx\n", debugstr_w(sourceinffile), debugstr_w(sourcemedialoc), mediatype, copystyle);
|
||||
FIXME("stub: source %s location %s ...\n", debugstr_w(sourceinffile),
|
||||
debugstr_w(sourcemedialoc));
|
||||
//return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupInitializeFileLogW(SETUPAPI.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue