mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
- Formatting fix. No code change
svn path=/trunk/; revision=38646
This commit is contained in:
parent
8560b3bcc3
commit
174b42a736
1 changed files with 285 additions and 280 deletions
|
@ -20,228 +20,223 @@ typedef DWORD (WINAPI *CMP_UNREGNOTIFY) (ULONG );
|
||||||
|
|
||||||
static HINSTANCE hSetupApi = NULL;
|
static HINSTANCE hSetupApi = NULL;
|
||||||
|
|
||||||
BOOL WINAPI _InternalLoadString
|
BOOL
|
||||||
(
|
WINAPI
|
||||||
HINSTANCE hInstance,
|
_InternalLoadString(HINSTANCE hInstance,
|
||||||
UINT uID,
|
UINT uID,
|
||||||
PUNICODE_STRING pwstrDest
|
PUNICODE_STRING pwstrDest)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
HRSRC hrsStringTable;
|
HRSRC hrsStringTable;
|
||||||
HGLOBAL hResource;
|
HGLOBAL hResource;
|
||||||
PWCHAR pStringTable;
|
PWCHAR pStringTable;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned l = uID % 16; /* (1) */
|
unsigned l = uID % 16; /* (1) */
|
||||||
|
|
||||||
/* parameter validation */
|
/* parameter validation */
|
||||||
if(IsBadWritePtr(pwstrDest, sizeof(UNICODE_STRING)))
|
if (IsBadWritePtr(pwstrDest, sizeof(UNICODE_STRING)))
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
find the string table. String tables are created by grouping, 16 by 16, string
|
|
||||||
resources whose identifiers, divided by 16, have the same integer quotient.
|
|
||||||
Holes in the numbering are filled with zero-length strings. String table ids
|
|
||||||
(actual resource ids) start from 1. See (1) and (2)
|
|
||||||
*/
|
|
||||||
/* TODO: some sort of cache, here, would be great */
|
|
||||||
hrsStringTable = FindResourceW
|
|
||||||
(
|
|
||||||
(HMODULE)hInstance,
|
|
||||||
MAKEINTRESOURCEW((uID / 16) + 1), /* (2) */
|
|
||||||
RT_STRING
|
|
||||||
);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(hrsStringTable == NULL) return FALSE;
|
|
||||||
|
|
||||||
/* load the string table into memory */
|
|
||||||
hResource = LoadResource((HMODULE)hInstance, hrsStringTable);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(hResource == NULL) return FALSE;
|
|
||||||
|
|
||||||
/* lock the resource into memory */
|
|
||||||
pStringTable = LockResource(hResource);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(pStringTable == NULL) return FALSE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
string tables are packed Unicode Pascal strings. The first WCHAR contains the
|
|
||||||
length, in characters, of the current string. Zero-length strings, if any, are
|
|
||||||
placeholders for unused slots, and should therefore be considered non-present.
|
|
||||||
See also (3). Here, we walk all the strings before that of interest
|
|
||||||
*/
|
|
||||||
for(i = 0; i < l; ++ i)
|
|
||||||
{
|
|
||||||
/* skip the length and the current string */
|
|
||||||
pStringTable += 1 + (*pStringTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we've reached the string of interest */
|
|
||||||
if((*pStringTable) == 0)
|
|
||||||
{
|
|
||||||
/* the string is empty (unallocated) */
|
|
||||||
SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
|
|
||||||
return FALSE; /* 3 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* string length in bytes */
|
|
||||||
pwstrDest->Length = pwstrDest->MaximumLength = (*pStringTable) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
/* string */
|
|
||||||
pwstrDest->Buffer = pStringTable + 1;
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
int WINAPI LoadStringA
|
|
||||||
(
|
|
||||||
HINSTANCE hInstance,
|
|
||||||
UINT uID,
|
|
||||||
LPSTR lpBuffer,
|
|
||||||
int nBufferMax
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNICODE_STRING wstrResStr;
|
|
||||||
ANSI_STRING strBuf;
|
|
||||||
INT retSize;
|
|
||||||
|
|
||||||
/* parameter validation */
|
|
||||||
|
|
||||||
if(nBufferMax < 1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0])))
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the UNICODE_STRING descriptor of the in-memory image of the string */
|
|
||||||
if(!_InternalLoadString(hInstance, uID, &wstrResStr))
|
|
||||||
{
|
|
||||||
/* failure */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
convert the string. The Unicode string may be in UTF-16 (multi-byte), so we
|
|
||||||
don't alter wstrResStr.Length, and let RtlUnicodeStringToAnsiString truncate
|
|
||||||
it, if necessary
|
|
||||||
*/
|
|
||||||
strBuf.Length = 0;
|
|
||||||
strBuf.MaximumLength = nBufferMax * sizeof(CHAR);
|
|
||||||
strBuf.Buffer = lpBuffer;
|
|
||||||
|
|
||||||
retSize = WideCharToMultiByte(CP_ACP, 0, wstrResStr.Buffer,
|
|
||||||
wstrResStr.Length / sizeof(WCHAR),
|
|
||||||
strBuf.Buffer, strBuf.MaximumLength, NULL, NULL);
|
|
||||||
|
|
||||||
if(!retSize)
|
|
||||||
{
|
|
||||||
/* failure */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strBuf.Length = retSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the ANSI string may not be null-terminated */
|
|
||||||
if(strBuf.Length >= strBuf.MaximumLength)
|
|
||||||
{
|
|
||||||
/* length greater than the buffer? whatever */
|
|
||||||
int nStringLen = strBuf.MaximumLength / sizeof(CHAR) - 1;
|
|
||||||
|
|
||||||
/* zero the last character in the buffer */
|
|
||||||
strBuf.Buffer[nStringLen] = 0;
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
return nStringLen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* zero the last character in the string */
|
|
||||||
strBuf.Buffer[strBuf.Length / sizeof(CHAR)] = 0;
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
return strBuf.Length / sizeof(CHAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
int WINAPI LoadStringW
|
|
||||||
(
|
|
||||||
HINSTANCE hInstance,
|
|
||||||
UINT uID,
|
|
||||||
LPWSTR lpBuffer,
|
|
||||||
int nBufferMax
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNICODE_STRING wstrResStr;
|
|
||||||
int nStringLen;
|
|
||||||
|
|
||||||
/* parameter validation */
|
|
||||||
if
|
|
||||||
(
|
|
||||||
(nBufferMax < 0) ||
|
|
||||||
(lpBuffer == NULL) ||
|
|
||||||
((nBufferMax > 0) && IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0]))) ||
|
|
||||||
/* undocumented: If nBufferMax is 0, LoadStringW will copy a pointer to the
|
|
||||||
in-memory image of the string to the specified buffer and return the length
|
|
||||||
of the string in WCHARs */
|
|
||||||
((nBufferMax == 0) && IsBadWritePtr(lpBuffer, sizeof(lpBuffer)))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the UNICODE_STRING descriptor of the in-memory image of the string */
|
|
||||||
if(!_InternalLoadString(hInstance, uID, &wstrResStr))
|
|
||||||
{
|
|
||||||
/* failure */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the length in characters */
|
|
||||||
nStringLen = wstrResStr.Length / sizeof(WCHAR);
|
|
||||||
|
|
||||||
if (nBufferMax > 0)
|
|
||||||
{
|
|
||||||
/* the buffer must be enough to contain the string and the null terminator */
|
|
||||||
if(nBufferMax < (nStringLen + 1))
|
|
||||||
{
|
{
|
||||||
/* otherwise, the string is truncated */
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
nStringLen = nBufferMax - 1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the string */
|
/*
|
||||||
memcpy(lpBuffer, wstrResStr.Buffer, nStringLen * sizeof(WCHAR));
|
find the string table. String tables are created by grouping, 16 by 16, string
|
||||||
|
resources whose identifiers, divided by 16, have the same integer quotient.
|
||||||
|
Holes in the numbering are filled with zero-length strings. String table ids
|
||||||
|
(actual resource ids) start from 1. See (1) and (2)
|
||||||
|
*/
|
||||||
|
/* TODO: some sort of cache, here, would be great */
|
||||||
|
hrsStringTable = FindResourceW((HMODULE)hInstance,
|
||||||
|
MAKEINTRESOURCEW((uID / 16) + 1), /* (2) */
|
||||||
|
RT_STRING);
|
||||||
|
|
||||||
/* null-terminate it */
|
/* failure */
|
||||||
lpBuffer[nStringLen] = 0;
|
if (hrsStringTable == NULL) return FALSE;
|
||||||
}
|
|
||||||
else
|
/* load the string table into memory */
|
||||||
{
|
hResource = LoadResource((HMODULE)hInstance, hrsStringTable);
|
||||||
*((LPWSTR*)lpBuffer) = wstrResStr.Buffer;
|
|
||||||
}
|
/* failure */
|
||||||
/* success */
|
if (hResource == NULL) return FALSE;
|
||||||
return nStringLen;
|
|
||||||
|
/* lock the resource into memory */
|
||||||
|
pStringTable = LockResource(hResource);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if (pStringTable == NULL) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
string tables are packed Unicode Pascal strings. The first WCHAR contains the
|
||||||
|
length, in characters, of the current string. Zero-length strings, if any, are
|
||||||
|
placeholders for unused slots, and should therefore be considered non-present.
|
||||||
|
See also (3). Here, we walk all the strings before that of interest
|
||||||
|
*/
|
||||||
|
for(i = 0; i < l; ++ i)
|
||||||
|
{
|
||||||
|
/* skip the length and the current string */
|
||||||
|
pStringTable += 1 + (*pStringTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we've reached the string of interest */
|
||||||
|
if ((*pStringTable) == 0)
|
||||||
|
{
|
||||||
|
/* the string is empty (unallocated) */
|
||||||
|
SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
|
||||||
|
return FALSE; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* string length in bytes */
|
||||||
|
pwstrDest->Length = pwstrDest->MaximumLength = (*pStringTable) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
/* string */
|
||||||
|
pwstrDest->Buffer = pStringTable + 1;
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
WINAPI
|
||||||
|
LoadStringA(HINSTANCE hInstance,
|
||||||
|
UINT uID,
|
||||||
|
LPSTR lpBuffer,
|
||||||
|
int nBufferMax)
|
||||||
|
{
|
||||||
|
UNICODE_STRING wstrResStr;
|
||||||
|
ANSI_STRING strBuf;
|
||||||
|
INT retSize;
|
||||||
|
|
||||||
|
/* parameter validation */
|
||||||
|
|
||||||
|
if (nBufferMax < 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0])))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the UNICODE_STRING descriptor of the in-memory image of the string */
|
||||||
|
if (!_InternalLoadString(hInstance, uID, &wstrResStr))
|
||||||
|
{
|
||||||
|
/* failure */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert the string. The Unicode string may be in UTF-16 (multi-byte), so we
|
||||||
|
don't alter wstrResStr.Length, and let RtlUnicodeStringToAnsiString truncate
|
||||||
|
it, if necessary
|
||||||
|
*/
|
||||||
|
strBuf.Length = 0;
|
||||||
|
strBuf.MaximumLength = nBufferMax * sizeof(CHAR);
|
||||||
|
strBuf.Buffer = lpBuffer;
|
||||||
|
|
||||||
|
retSize = WideCharToMultiByte(CP_ACP,
|
||||||
|
0,
|
||||||
|
wstrResStr.Buffer,
|
||||||
|
wstrResStr.Length / sizeof(WCHAR),
|
||||||
|
strBuf.Buffer,
|
||||||
|
strBuf.MaximumLength,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!retSize)
|
||||||
|
{
|
||||||
|
/* failure */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strBuf.Length = retSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the ANSI string may not be null-terminated */
|
||||||
|
if (strBuf.Length >= strBuf.MaximumLength)
|
||||||
|
{
|
||||||
|
/* length greater than the buffer? whatever */
|
||||||
|
int nStringLen = strBuf.MaximumLength / sizeof(CHAR) - 1;
|
||||||
|
|
||||||
|
/* zero the last character in the buffer */
|
||||||
|
strBuf.Buffer[nStringLen] = 0;
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return nStringLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* zero the last character in the string */
|
||||||
|
strBuf.Buffer[strBuf.Length / sizeof(CHAR)] = 0;
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return strBuf.Length / sizeof(CHAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
WINAPI
|
||||||
|
LoadStringW(HINSTANCE hInstance,
|
||||||
|
UINT uID,
|
||||||
|
LPWSTR lpBuffer,
|
||||||
|
int nBufferMax)
|
||||||
|
{
|
||||||
|
UNICODE_STRING wstrResStr;
|
||||||
|
int nStringLen;
|
||||||
|
|
||||||
|
/* parameter validation */
|
||||||
|
if ((nBufferMax < 0) || (lpBuffer == NULL) ||
|
||||||
|
((nBufferMax > 0) && IsBadWritePtr(lpBuffer, nBufferMax * sizeof(lpBuffer[0]))) ||
|
||||||
|
/* undocumented: If nBufferMax is 0, LoadStringW will copy a pointer to the
|
||||||
|
in-memory image of the string to the specified buffer and return the length
|
||||||
|
of the string in WCHARs */
|
||||||
|
((nBufferMax == 0) && IsBadWritePtr(lpBuffer, sizeof(lpBuffer))))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the UNICODE_STRING descriptor of the in-memory image of the string */
|
||||||
|
if (!_InternalLoadString(hInstance, uID, &wstrResStr))
|
||||||
|
{
|
||||||
|
/* failure */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the length in characters */
|
||||||
|
nStringLen = wstrResStr.Length / sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (nBufferMax > 0)
|
||||||
|
{
|
||||||
|
/* the buffer must be enough to contain the string and the null terminator */
|
||||||
|
if (nBufferMax < (nStringLen + 1))
|
||||||
|
{
|
||||||
|
/* otherwise, the string is truncated */
|
||||||
|
nStringLen = nBufferMax - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy the string */
|
||||||
|
memcpy(lpBuffer, wstrResStr.Buffer, nStringLen * sizeof(WCHAR));
|
||||||
|
|
||||||
|
/* null-terminate it */
|
||||||
|
lpBuffer[nStringLen] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*((LPWSTR*)lpBuffer) = wstrResStr.Buffer;
|
||||||
|
}
|
||||||
|
/* success */
|
||||||
|
return nStringLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,44 +245,49 @@ int WINAPI LoadStringW
|
||||||
*/
|
*/
|
||||||
HDEVNOTIFY
|
HDEVNOTIFY
|
||||||
WINAPI
|
WINAPI
|
||||||
RegisterDeviceNotificationW(
|
RegisterDeviceNotificationW(HANDLE hRecipient,
|
||||||
HANDLE hRecipient,
|
LPVOID NotificationFilter,
|
||||||
LPVOID NotificationFilter,
|
DWORD Flags)
|
||||||
DWORD Flags
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
DWORD ConfigRet = 0;
|
DWORD ConfigRet = 0;
|
||||||
CMP_REGNOTIFY RegNotify = NULL;
|
CMP_REGNOTIFY RegNotify = NULL;
|
||||||
HDEVNOTIFY hDevNotify = NULL;
|
HDEVNOTIFY hDevNotify = NULL;
|
||||||
if ( hSetupApi == NULL ) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
|
|
||||||
if ( hSetupApi == NULL ) return NULL;
|
if (hSetupApi == NULL) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
|
||||||
RegNotify = (CMP_REGNOTIFY) GetProcAddress ( hSetupApi, "CMP_RegisterNotification");
|
if (hSetupApi == NULL) return NULL;
|
||||||
if (RegNotify == NULL)
|
|
||||||
{
|
RegNotify = (CMP_REGNOTIFY) GetProcAddress(hSetupApi, "CMP_RegisterNotification");
|
||||||
FreeLibrary ( hSetupApi );
|
if (RegNotify == NULL)
|
||||||
hSetupApi = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ConfigRet = RegNotify ( hRecipient, NotificationFilter, Flags, (PULONG) &hDevNotify);
|
|
||||||
if (ConfigRet != CR_SUCCESS)
|
|
||||||
{
|
|
||||||
switch (ConfigRet)
|
|
||||||
{
|
{
|
||||||
case CR_OUT_OF_MEMORY:
|
FreeLibrary(hSetupApi);
|
||||||
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
|
hSetupApi = NULL;
|
||||||
break;
|
return NULL;
|
||||||
case CR_INVALID_POINTER:
|
|
||||||
SetLastError (ERROR_INVALID_PARAMETER);
|
|
||||||
break;
|
|
||||||
case CR_INVALID_DATA:
|
|
||||||
SetLastError (ERROR_INVALID_DATA);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return hDevNotify;
|
ConfigRet = RegNotify(hRecipient, NotificationFilter, Flags, (PULONG) &hDevNotify);
|
||||||
|
if (ConfigRet != CR_SUCCESS)
|
||||||
|
{
|
||||||
|
switch (ConfigRet)
|
||||||
|
{
|
||||||
|
case CR_OUT_OF_MEMORY:
|
||||||
|
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CR_INVALID_POINTER:
|
||||||
|
SetLastError (ERROR_INVALID_PARAMETER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CR_INVALID_DATA:
|
||||||
|
SetLastError (ERROR_INVALID_DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hDevNotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,38 +296,43 @@ RegisterDeviceNotificationW(
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
UnregisterDeviceNotification(
|
UnregisterDeviceNotification(HDEVNOTIFY Handle)
|
||||||
HDEVNOTIFY Handle)
|
|
||||||
{
|
{
|
||||||
DWORD ConfigRet = 0;
|
DWORD ConfigRet = 0;
|
||||||
CMP_UNREGNOTIFY UnRegNotify = NULL;
|
CMP_UNREGNOTIFY UnRegNotify = NULL;
|
||||||
if ( hSetupApi == NULL ) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
|
|
||||||
if ( hSetupApi == NULL ) return FALSE;
|
if (hSetupApi == NULL) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
|
||||||
UnRegNotify = (CMP_UNREGNOTIFY) GetProcAddress ( hSetupApi, "CMP_UnregisterNotification");
|
if (hSetupApi == NULL) return FALSE;
|
||||||
if (UnRegNotify == NULL)
|
|
||||||
{
|
UnRegNotify = (CMP_UNREGNOTIFY) GetProcAddress(hSetupApi, "CMP_UnregisterNotification");
|
||||||
FreeLibrary ( hSetupApi );
|
if (UnRegNotify == NULL)
|
||||||
hSetupApi = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
ConfigRet = UnRegNotify ( (ULONG) Handle );
|
|
||||||
if (ConfigRet != CR_SUCCESS)
|
|
||||||
{
|
|
||||||
switch (ConfigRet)
|
|
||||||
{
|
{
|
||||||
case CR_INVALID_POINTER:
|
FreeLibrary(hSetupApi);
|
||||||
SetLastError (ERROR_INVALID_PARAMETER);
|
hSetupApi = NULL;
|
||||||
break;
|
return FALSE;
|
||||||
case CR_INVALID_DATA:
|
|
||||||
SetLastError (ERROR_INVALID_DATA);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
|
||||||
}
|
ConfigRet = UnRegNotify((ULONG) Handle );
|
||||||
return TRUE;
|
if (ConfigRet != CR_SUCCESS)
|
||||||
|
{
|
||||||
|
switch (ConfigRet)
|
||||||
|
{
|
||||||
|
case CR_INVALID_POINTER:
|
||||||
|
SetLastError (ERROR_INVALID_PARAMETER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CR_INVALID_DATA:
|
||||||
|
SetLastError (ERROR_INVALID_DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue