Author: hpoussin
Date: Mon May 29 17:32:51 2006
New Revision: 22109
URL:
http://svn.reactos.ru/svn/reactos?rev=22109&view=rev
Log:
- Implement SetupCopyOEMInfW
- Correctly sort drivers by rank and by date
- Fix memory corruption if %SYSTEMROOT% was longer than 128 chars
Modified:
trunk/reactos/dll/win32/setupapi/devinst.c
trunk/reactos/dll/win32/setupapi/install.c
trunk/reactos/dll/win32/setupapi/setupapi_private.h
trunk/reactos/dll/win32/setupapi/stubs.c
Modified: trunk/reactos/dll/win32/setupapi/devinst.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/setupapi/devinst.…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/devinst.c (original)
+++ trunk/reactos/dll/win32/setupapi/devinst.c Mon May 29 17:32:51 2006
@@ -5486,14 +5486,15 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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)
@@ -8064,6 +8056,35 @@
memcpy(&lpFullGuidString[1], lpGuidString, RequiredSize * sizeof(WCHAR));
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
@@ -8105,7 +8126,7 @@
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 @@
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 @@
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)
Modified: trunk/reactos/dll/win32/setupapi/install.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/setupapi/install.…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/install.c (original)
+++ trunk/reactos/dll/win32/setupapi/install.c Mon May 29 17:32:51 2006
@@ -22,6 +22,10 @@
#include "setupapi_private.h"
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 @@
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;
+}
Modified: trunk/reactos/dll/win32/setupapi/setupapi_private.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/setupapi/setupapi…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/setupapi_private.h (original)
+++ trunk/reactos/dll/win32/setupapi/setupapi_private.h Mon May 29 17:32:51 2006
@@ -78,10 +78,9 @@
* 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];
};
Modified: trunk/reactos/dll/win32/setupapi/stubs.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/setupapi/stubs.c?…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/stubs.c (original)
+++ trunk/reactos/dll/win32/setupapi/stubs.c Mon May 29 17:32:51 2006
@@ -48,21 +48,6 @@
{
FIXME("\n");
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;
}
/***********************************************************************