[KERNEL32]

- Minor cleanup, better flag names (thanks to ProcessHacker team for the good names and values).
- Return error in failure path of BasepGetModuleHandleExW.
- Optimize GetModuleHandleExA so that it calls the internal routine directly, without going through GetModuleHandleExW first and thus validating parameters second time.

svn path=/trunk/; revision=51253
This commit is contained in:
Aleksey Bragin 2011-04-04 19:35:24 +00:00
parent 15474a66e9
commit 7fcd953546
3 changed files with 49 additions and 40 deletions

View file

@ -15,9 +15,6 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
#define LDR_LOCK_HELD 0x2
#define LDR_LOCK_FREE 0x1
LONG LdrpLoaderLockAcquisitonCount; LONG LdrpLoaderLockAcquisitonCount;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -38,7 +35,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
if (Flags & ~1) if (Flags & ~1)
{ {
/* Flags are invalid, check how to fail */ /* Flags are invalid, check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@ -60,7 +57,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n"); DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
/* Invalid cookie, check how to fail */ /* Invalid cookie, check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@ -73,7 +70,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
} }
/* Ready to release the lock */ /* Ready to release the lock */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* Do a direct leave */ /* Do a direct leave */
RtlLeaveCriticalSection(&LdrpLoaderLock); RtlLeaveCriticalSection(&LdrpLoaderLock);
@ -118,11 +115,11 @@ LdrLockLoaderLock(IN ULONG Flags,
if (Cookie) *Cookie = 0; if (Cookie) *Cookie = 0;
/* Validate the flags */ /* Validate the flags */
if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS | if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS |
LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)) LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY))
{ {
/* Flags are invalid, check how to fail */ /* Flags are invalid, check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@ -136,7 +133,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!Cookie) if (!Cookie)
{ {
/* No cookie check how to fail */ /* No cookie check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_3); RtlRaiseStatus(STATUS_INVALID_PARAMETER_3);
@ -150,7 +147,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result)) if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result))
{ {
/* No pointer to return the data to */ /* No pointer to return the data to */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@ -164,7 +161,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if (InInit) return STATUS_SUCCESS; if (InInit) return STATUS_SUCCESS;
/* Check what locking semantic to use */ /* Check what locking semantic to use */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* Check if we should enter or simply try */ /* Check if we should enter or simply try */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
@ -173,13 +170,13 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{ {
/* It's locked */ /* It's locked */
*Result = LDR_LOCK_HELD; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
goto Quickie; goto Quickie;
} }
else else
{ {
/* It worked */ /* It worked */
*Result = LDR_LOCK_FREE; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
} }
else else
@ -188,7 +185,7 @@ LdrLockLoaderLock(IN ULONG Flags,
RtlEnterCriticalSection(&LdrpLoaderLock); RtlEnterCriticalSection(&LdrpLoaderLock);
/* See if result was requested */ /* See if result was requested */
if (Result) *Result = LDR_LOCK_FREE; if (Result) *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
/* Increase the acquisition count */ /* Increase the acquisition count */
@ -209,13 +206,13 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{ {
/* It's locked */ /* It's locked */
*Result = LDR_LOCK_HELD; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
_SEH2_YIELD(return STATUS_SUCCESS); _SEH2_YIELD(return STATUS_SUCCESS);
} }
else else
{ {
/* It worked */ /* It worked */
*Result = LDR_LOCK_FREE; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
} }
else else
@ -224,7 +221,7 @@ LdrLockLoaderLock(IN ULONG Flags,
RtlEnterCriticalSection(&LdrpLoaderLock); RtlEnterCriticalSection(&LdrpLoaderLock);
/* See if result was requested */ /* See if result was requested */
if (Result) *Result = LDR_LOCK_FREE; if (Result) *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
/* Increase the acquisition count */ /* Increase the acquisition count */

View file

@ -22,7 +22,7 @@ typedef struct tagLOADPARMS32 {
extern BOOLEAN InWindows; extern BOOLEAN InWindows;
extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle; extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL 1 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR 1
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3
@ -47,14 +47,14 @@ BasepGetModuleHandleExParameterValidation(DWORD dwFlags,
) )
{ {
BaseSetLastNTError(STATUS_INVALID_PARAMETER_1); BaseSetLastNTError(STATUS_INVALID_PARAMETER_1);
return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL; return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR;
} }
/* Check 2nd parameter */ /* Check 2nd parameter */
if (!phModule) if (!phModule)
{ {
BaseSetLastNTError(STATUS_INVALID_PARAMETER_2); BaseSetLastNTError(STATUS_INVALID_PARAMETER_2);
return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL; return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR;
} }
/* Return what we have according to the module name */ /* Return what we have according to the module name */
@ -578,7 +578,7 @@ GetModuleFileNameW(HINSTANCE hModule,
Peb = NtCurrentPeb (); Peb = NtCurrentPeb ();
/* Acquire a loader lock */ /* Acquire a loader lock */
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS, NULL, &Cookie); LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);
/* Traverse the module list */ /* Traverse the module list */
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList; ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
@ -615,7 +615,7 @@ GetModuleFileNameW(HINSTANCE hModule,
} _SEH2_END } _SEH2_END
/* Release the loader lock */ /* Release the loader lock */
LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS, Cookie); LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
return Length / sizeof(WCHAR); return Length / sizeof(WCHAR);
} }
@ -709,7 +709,8 @@ BasepGetModuleHandleExW(BOOLEAN NoLock, DWORD dwPublicFlags, LPCWSTR lpwModuleNa
hModule = GetModuleHandleForUnicodeString(&ModuleNameU); hModule = GetModuleHandleForUnicodeString(&ModuleNameU);
if (!hModule) if (!hModule)
{ {
// FIXME: Status?! /* Last error is already set, so just return failure by setting status */
Status = STATUS_DLL_NOT_FOUND;
goto quickie; goto quickie;
} }
} }
@ -737,6 +738,10 @@ BasepGetModuleHandleExW(BOOLEAN NoLock, DWORD dwPublicFlags, LPCWSTR lpwModuleNa
hModule); hModule);
} }
/* Set last error in case of failure */
if (!NT_SUCCESS(Status))
SetLastErrorByStatus(Status);
quickie: quickie:
/* Unlock loader lock if it was acquired */ /* Unlock loader lock if it was acquired */
if (!NoLock) if (!NoLock)
@ -745,10 +750,6 @@ quickie:
ASSERT(NT_SUCCESS(Status2)); ASSERT(NT_SUCCESS(Status2));
} }
/* Set last error in case of failure */
if (!NT_SUCCESS(Status))
SetLastErrorByStatus(Status);
/* Set the module handle to the caller */ /* Set the module handle to the caller */
if (phModule) *phModule = hModule; if (phModule) *phModule = hModule;
@ -827,7 +828,7 @@ GetModuleHandleExW(IN DWORD dwFlags,
dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule); dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule);
/* If result is invalid parameter - return failure */ /* If result is invalid parameter - return failure */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL) return FALSE; if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
/* If result is 2, there is no need to do anything - return success. */ /* If result is 2, there is no need to do anything - return success. */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE; if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
@ -855,13 +856,14 @@ GetModuleHandleExA(IN DWORD dwFlags,
{ {
PUNICODE_STRING lpModuleNameW; PUNICODE_STRING lpModuleNameW;
DWORD dwValid; DWORD dwValid;
BOOL Ret; BOOL Ret = FALSE;
NTSTATUS Status;
/* Validate parameters */ /* Validate parameters */
dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, (LPCWSTR)lpModuleName, phModule); dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, (LPCWSTR)lpModuleName, phModule);
/* If result is invalid parameter - return failure */ /* If result is invalid parameter - return failure */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL) return FALSE; if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
/* If result is 2, there is no need to do anything - return success. */ /* If result is 2, there is no need to do anything - return success. */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE; if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
@ -869,10 +871,11 @@ GetModuleHandleExA(IN DWORD dwFlags,
/* Check if we don't need to convert the name */ /* Check if we don't need to convert the name */
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
{ {
/* Call the W version of the API without conversion */ /* Call the extended version of the API without conversion */
Ret = GetModuleHandleExW(dwFlags, Status = BasepGetModuleHandleExW(FALSE,
(LPCWSTR)lpModuleName, dwFlags,
phModule); (LPCWSTR)lpModuleName,
phModule);
} }
else else
{ {
@ -882,12 +885,17 @@ GetModuleHandleExA(IN DWORD dwFlags,
/* Return FALSE if conversion failed */ /* Return FALSE if conversion failed */
if (!lpModuleNameW) return FALSE; if (!lpModuleNameW) return FALSE;
/* Call the W version of the API */ /* Call the extended version of the API */
Ret = GetModuleHandleExW(dwFlags, Status = BasepGetModuleHandleExW(FALSE,
lpModuleNameW->Buffer, dwFlags,
phModule); lpModuleNameW->Buffer,
phModule);
} }
/* If result was successful - return true */
if (NT_SUCCESS(Status))
Ret = TRUE;
/* Return result */ /* Return result */
return Ret; return Ret;
} }

View file

@ -71,8 +71,12 @@ Author:
// //
// LdrLockLoaderLock Flags // LdrLockLoaderLock Flags
// //
#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS 0x00000001 #define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001
#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002 #define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID 0
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED 1
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED 2
// //
// FIXME: THIS SHOULD *NOT* BE USED! // FIXME: THIS SHOULD *NOT* BE USED!