mirror of
https://github.com/reactos/reactos.git
synced 2025-06-23 01:30:16 +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
4 changed files with 208 additions and 65 deletions
|
@ -5486,14 +5486,15 @@ AddDriverToList(
|
||||||
driverInfo->Details.InfFileName[MAX_PATH - 1] = '\0';
|
driverInfo->Details.InfFileName[MAX_PATH - 1] = '\0';
|
||||||
|
|
||||||
/* Fill InfDate field */
|
/* Fill InfDate field */
|
||||||
/* FIXME: hFile = CreateFile(driverInfo->Details.InfFileName,
|
hFile = CreateFile(
|
||||||
|
InfFile,
|
||||||
GENERIC_READ, FILE_SHARE_READ,
|
GENERIC_READ, FILE_SHARE_READ,
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
Result = GetFileTime(hFile, NULL, NULL, &driverInfo->Details.InfDate);
|
Result = GetFileTime(hFile, NULL, NULL, &driverInfo->Details.InfDate);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
goto cleanup;*/
|
goto cleanup;
|
||||||
|
|
||||||
/* Fill SectionName field */
|
/* Fill SectionName field */
|
||||||
Result = SetupGetStringFieldW(
|
Result = SetupGetStringFieldW(
|
||||||
|
@ -5576,10 +5577,10 @@ AddDriverToList(
|
||||||
struct DriverInfoElement *CurrentDriver;
|
struct DriverInfoElement *CurrentDriver;
|
||||||
CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
|
CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
|
||||||
if (CurrentDriver->DriverRank > Rank ||
|
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 */
|
/* Insert before the current item */
|
||||||
InsertHeadList(PreviousEntry, &driverInfo->ListEntry);
|
InsertHeadList(PreviousEntry->Blink, &driverInfo->ListEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PreviousEntry = PreviousEntry->Flink;
|
PreviousEntry = PreviousEntry->Flink;
|
||||||
|
@ -5858,17 +5859,14 @@ done:
|
||||||
|
|
||||||
static struct InfFileDetails *
|
static struct InfFileDetails *
|
||||||
CreateInfFileDetails(
|
CreateInfFileDetails(
|
||||||
IN LPCWSTR InfFileName)
|
IN LPCWSTR FullInfFileName)
|
||||||
{
|
{
|
||||||
struct InfFileDetails *details;
|
struct InfFileDetails *details;
|
||||||
PWCHAR last;
|
PWCHAR last;
|
||||||
DWORD Needed;
|
DWORD Needed;
|
||||||
|
|
||||||
last = strrchrW(InfFileName, '\\');
|
|
||||||
Needed = FIELD_OFFSET(struct InfFileDetails, szData)
|
Needed = FIELD_OFFSET(struct InfFileDetails, szData)
|
||||||
+ strlenW(InfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
+ strlenW(FullInfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||||
if (last != NULL)
|
|
||||||
Needed += (last - InfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
|
||||||
|
|
||||||
details = HeapAlloc(GetProcessHeap(), 0, Needed);
|
details = HeapAlloc(GetProcessHeap(), 0, Needed);
|
||||||
if (!details)
|
if (!details)
|
||||||
|
@ -5878,17 +5876,18 @@ CreateInfFileDetails(
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(details, 0, Needed);
|
memset(details, 0, Needed);
|
||||||
|
strcpyW(details->szData, FullInfFileName);
|
||||||
|
last = strrchrW(details->szData, '\\');
|
||||||
if (last)
|
if (last)
|
||||||
{
|
{
|
||||||
details->DirectoryName = details->szData;
|
details->DirectoryName = details->szData;
|
||||||
details->FullInfFileName = &details->szData[last - InfFileName + 1];
|
details->FileName = last + 1;
|
||||||
strncpyW(details->DirectoryName, InfFileName, last - InfFileName);
|
*last = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
details->FullInfFileName = details->szData;
|
details->FileName = details->szData;
|
||||||
strcpyW(details->FullInfFileName, InfFileName);
|
|
||||||
ReferenceInfFile(details);
|
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)
|
if (details->hInf == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, details);
|
HeapFree(GetProcessHeap(), 0, details);
|
||||||
|
@ -6022,20 +6021,13 @@ SetupDiBuildDriverInfoList(
|
||||||
LPCWSTR filename;
|
LPCWSTR filename;
|
||||||
LPWSTR pFullFilename;
|
LPWSTR pFullFilename;
|
||||||
|
|
||||||
if (InstallParams.Flags & DI_ENUMSINGLEINF)
|
if (!(InstallParams.Flags & DI_ENUMSINGLEINF) && *InstallParams.DriverPath)
|
||||||
{
|
|
||||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
|
|
||||||
if (!FullInfFileName)
|
|
||||||
goto done;
|
|
||||||
pFullFilename = &FullInfFileName[0];
|
|
||||||
}
|
|
||||||
else if (*InstallParams.DriverPath)
|
|
||||||
{
|
{
|
||||||
DWORD len;
|
DWORD len;
|
||||||
len = GetFullPathNameW(InstallParams.DriverPath, 0, NULL, NULL);
|
len = GetFullPathNameW(InstallParams.DriverPath, 0, NULL, NULL);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
goto done;
|
goto done;
|
||||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, len + MAX_PATH);
|
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, (len + 1 + MAX_PATH) * sizeof(WCHAR));
|
||||||
if (!FullInfFileName)
|
if (!FullInfFileName)
|
||||||
goto done;
|
goto done;
|
||||||
len = GetFullPathNameW(InstallParams.DriverPath, len, FullInfFileName, NULL);
|
len = GetFullPathNameW(InstallParams.DriverPath, len, FullInfFileName, NULL);
|
||||||
|
@ -6047,7 +6039,7 @@ SetupDiBuildDriverInfoList(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
|
FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
|
||||||
if (!FullInfFileName)
|
if (!FullInfFileName)
|
||||||
goto done;
|
goto done;
|
||||||
pFullFilename = &FullInfFileName[0];
|
pFullFilename = &FullInfFileName[0];
|
||||||
|
@ -8048,7 +8040,7 @@ SetupDiInstallDevice(
|
||||||
pSectionName = &SectionName[strlenW(SectionName)];
|
pSectionName = &SectionName[strlenW(SectionName)];
|
||||||
|
|
||||||
/* Get information from [Version] section */
|
/* 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;
|
goto cleanup;
|
||||||
/* Format ClassGuid to a string */
|
/* Format ClassGuid to a string */
|
||||||
if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
|
if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
|
||||||
|
@ -8065,6 +8057,35 @@ SetupDiInstallDevice(
|
||||||
lpFullGuidString[RequiredSize + 1] = '}';
|
lpFullGuidString[RequiredSize + 1] = '}';
|
||||||
lpFullGuidString[RequiredSize + 2] = '\0';
|
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 */
|
/* Open/Create driver key information */
|
||||||
#if _WIN32_WINNT >= 0x502
|
#if _WIN32_WINNT >= 0x502
|
||||||
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
|
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("DriverDate : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
|
||||||
TRACE("DriverDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
|
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("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("InfSection : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName));
|
||||||
TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
|
TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
|
||||||
TRACE("MatchingDeviceId: '%s'\n", debugstr_w(SelectedDriver->MatchingId));
|
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));
|
rc = RegSetValueEx(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
if (rc == ERROR_SUCCESS)
|
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)
|
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));
|
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)
|
if (rc == ERROR_SUCCESS)
|
||||||
|
@ -8156,26 +8177,6 @@ SetupDiInstallDevice(
|
||||||
if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
|
if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
|
||||||
RebootRequired = TRUE;
|
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 */
|
/* Open device registry key */
|
||||||
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
|
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
|
||||||
if (hKey == INVALID_HANDLE_VALUE)
|
if (hKey == INVALID_HANDLE_VALUE)
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
|
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 */
|
/* info passed to callback functions dealing with files */
|
||||||
struct files_callback_info
|
struct files_callback_info
|
||||||
{
|
{
|
||||||
|
@ -1661,3 +1665,157 @@ cleanup:
|
||||||
TRACE("Returning %d\n", ret);
|
TRACE("Returning %d\n", ret);
|
||||||
return 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.
|
* be NULL if the file is already in %SYSTEMROOT%\Inf.
|
||||||
* Points into szData at then end of the structure */
|
* Points into szData at then end of the structure */
|
||||||
PCWSTR DirectoryName;
|
PCWSTR DirectoryName;
|
||||||
/* Contains the full file name of the .inf file. However, the directory
|
/* Contains the .inf file name (without directory name).
|
||||||
* part may be missing if the file is already in %SYSTEMROOT%\Inf.
|
|
||||||
* Points into szData at then end of the structure */
|
* Points into szData at then end of the structure */
|
||||||
PCWSTR FullInfFileName;
|
PCWSTR FileName;
|
||||||
|
|
||||||
WCHAR szData[ANYSIZE_ARRAY];
|
WCHAR szData[ANYSIZE_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,21 +50,6 @@ BOOL WINAPI SetupDiGetDeviceInfoListDetailA(HDEVINFO devinfo, PSP_DEVINFO_LIST_D
|
||||||
return FALSE;
|
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.@)
|
* SetupInitializeFileLogW(SETUPAPI.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue