Author: mjmartin
Date: Mon Apr 4 21:50:24 2011
New Revision: 51255
URL: http://svn.reactos.org/svn/reactos?rev=51255&view=rev
Log:
[Win32k]
- co_MsqDispatchOneSentMessage: After calling the windows procedure check if the message was a callback. If so place the message into the calling MessageQueue. Also check if the current MessageQueue is the calling MessageQueue in which case dont call the Windows procedure but call the callback routine. SendMessageCallback is now properly implemented.
- Remove the use of MSQ_SENTNOWAIT and instead use the SenderQueue and CallBackSenderQueue members to determine if the MessageQueues need to be dereferenced.
- Modify co_MsqSendMessage to accept more parameters so that it can handle Notification, Callback and Internal messages. These changes make this function more complex but removes duplicate code in messages.c and move the handling for all queued messages in one location.
- co_IntSendMessageWithCallBack: If the callback is for the same Message Queue, call it vice queuing it.
Insert the message into the MessageQueue before waking the thread to handle the message. Should fix bug 5580.
Modified:
trunk/reactos/subsystems/win32/win32k/ntuser/event.c
trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/event.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/event.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/event.c [iso-8859-1] Mon Apr 4 21:50:24 2011
@@ -115,15 +115,19 @@
/* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
- Status = co_MsqSendMessage( pEH->head.pti->MessageQueue,
+ Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue,
+ pEH->head.pti->MessageQueue,
hwnd,
event,
0,
- (LPARAM)pEP,
+ (LPARAM)pEP,
+ FALSE,
+ NULL,
+ 0,
300,
TRUE,
MSQ_ISEVENT,
- &uResult);
+ &uResult);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(pEP, TAG_HOOK);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] Mon Apr 4 21:50:24 2011
@@ -88,15 +88,19 @@
/* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
- Status = co_MsqSendMessage( pti->MessageQueue,
+ Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue,
+ pti->MessageQueue,
IntToPtr(Code), // hWnd
Hook->HookId, // Msg
wParam,
- (LPARAM)pHP,
+ (LPARAM)pHP,
+ FALSE,
+ NULL,
+ 0,
uTimeout,
Block,
MSQ_ISHOOK,
- &uResult);
+ &uResult);
if (!NT_SUCCESS(Status))
{
DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] Mon Apr 4 21:50:24 2011
@@ -1261,11 +1261,15 @@
do
{
- Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
+ Status = co_MsqSendMessage(((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue,
+ Window->head.pti->MessageQueue,
hWnd,
Msg,
wParam,
lParam,
+ FALSE,
+ NULL,
+ 0,
uTimeout,
(uFlags & SMTO_BLOCK),
MSQ_NORMAL,
@@ -1354,6 +1358,7 @@
LPARAM lParam)
{
ULONG_PTR Result = 0;
+ /* Piggyback off CallBack */
co_IntSendMessageWithCallBack(hWnd,
Msg,
wParam,
@@ -1372,12 +1377,12 @@
*/
LRESULT FASTCALL
co_IntSendMessageWithCallBack( HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- SENDASYNCPROC CompletionCallback,
- ULONG_PTR CompletionCallbackContext,
- ULONG_PTR *uResult)
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ SENDASYNCPROC CompletionCallback,
+ ULONG_PTR CompletionCallbackContext,
+ ULONG_PTR *uResult)
{
ULONG_PTR Result;
PWND Window = NULL;
@@ -1437,7 +1442,7 @@
}
/* If this is not a callback and it can be sent now, then send it. */
- if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
ObReferenceObject(Win32Thread->pEThread);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
@@ -1452,11 +1457,20 @@
*uResult = Result;
}
ObDereferenceObject(Win32Thread->pEThread);
+
+ if (CompletionCallback)
+ {
+ co_IntCallSentMessageCallback(CompletionCallback,
+ hWnd,
+ Msg,
+ CompletionCallbackContext,
+ Result);
+ }
}
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
@@ -1480,18 +1494,21 @@
Message->lResult = 0;
Message->QS_Flags = 0;
Message->SenderQueue = NULL; // mjmartin, you are right! This is null.
- Message->CallBackSenderQueue = Win32Thread->MessageQueue;
-
+ if (CompletionCallback)
+ Message->CallBackSenderQueue = Win32Thread->MessageQueue;
+ else
+ Message->CallBackSenderQueue = NULL;
IntReferenceMessageQueue(Window->head.pti->MessageQueue);
Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext;
- Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
- Message->HasPackedLParam = (lParamBufferSize > 0);
+ Message->HookMessage = MSQ_NORMAL;
+ Message->HasPackedLParam = (lParamBufferSize > -1);
Message->QS_Flags = QS_SENDMESSAGE;
+ if (CompletionCallback)
+ InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
+ InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE);
-
- InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
RETURN(TRUE);
@@ -2112,7 +2129,7 @@
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
- wParam,
+ wParam,
lParam,
SMTO_NORMAL,
2000,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Mon Apr 4 21:50:24 2011
@@ -423,7 +423,7 @@
PLIST_ENTRY Entry;
LRESULT Result;
PTHREADINFO pti;
-
+
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
{
return(FALSE);
@@ -466,6 +466,18 @@
Message->Msg.wParam,
Message->Msg.lParam);
}
+ else if ((Message->CompletionCallback)
+ && (Message->CallBackSenderQueue == MessageQueue))
+ { /* Call the callback routine */
+ ASSERT(Message->QS_Flags & QS_SMRESULT);
+ co_IntCallSentMessageCallback(Message->CompletionCallback,
+ Message->Msg.hwnd,
+ Message->Msg.message,
+ Message->CompletionCallbackContext,
+ Message->lResult);
+ /* Set callback to NULL to prevent reentry */
+ Message->CompletionCallback = NULL;
+ }
else
{ /* Call the window procedure. */
Result = co_IntSendMessage( Message->Msg.hwnd,
@@ -478,8 +490,23 @@
to be cleaned up on thread termination anymore */
RemoveEntryList(&Message->ListEntry);
- /* remove the message from the dispatching list if needed, so lock the sender's message queue */
- if (!(Message->HookMessage & MSQ_SENTNOWAIT))
+ if (Message->CompletionCallback)
+ {
+ if (Message->CallBackSenderQueue)
+ {
+ Message->lResult = Result;
+ Message->QS_Flags |= QS_SMRESULT;
+
+ /* queue it in the callers message queue */
+ InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry);
+ MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE);
+ IntDereferenceMessageQueue(Message->CallBackSenderQueue);
+ }
+ return (TRUE);
+ }
+
+ /* remove the message from the dispatching list if there is a SenderQueue, so lock the sender's message queue */
+ if ((Message->SenderQueue) || (Message->CallBackSenderQueue))
{
if (Message->DispatchingListEntry.Flink != NULL)
{
@@ -513,18 +540,8 @@
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
}
- /* Call the callback if the message was sent with SendMessageCallback */
- if (Message->CompletionCallback != NULL)
- {
- co_IntCallSentMessageCallback(Message->CompletionCallback,
- Message->Msg.hwnd,
- Message->Msg.message,
- Message->CompletionCallbackContext,
- Result);
- }
-
- /* Only if it is not a no wait message */
- if (!(Message->HookMessage & MSQ_SENTNOWAIT))
+ /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */
+ if (Message->SenderQueue)
{
IntDereferenceMessageQueue(Message->SenderQueue);
IntDereferenceMessageQueue(MessageQueue);
@@ -588,10 +605,11 @@
RemoveEntryList(&SentMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags);
- /* remove the message from the dispatching list if neede */
- if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
+ /* If there was a SenderQueue then remove the message from this threads dispatching list */
+ if (((SentMessage->SenderQueue) || (SentMessage->CallBackSenderQueue))
&& (SentMessage->DispatchingListEntry.Flink != NULL))
{
+ SentMessage->CallBackSenderQueue = NULL;
RemoveEntryList(&SentMessage->DispatchingListEntry);
}
@@ -607,8 +625,8 @@
ExFreePool((PVOID)SentMessage->Msg.lParam);
}
- /* Only if it is not a no wait message */
- if (!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
+ /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */
+ if (SentMessage->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(MessageQueue);
@@ -628,8 +646,9 @@
}
NTSTATUS FASTCALL
-co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
+co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQueue,
+ HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL HasPackedLParam,
+ SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext,
UINT uTimeout, BOOL Block, INT HookMessage,
ULONG_PTR *uResult)
{
@@ -637,55 +656,100 @@
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus;
- PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout;
PLIST_ENTRY Entry;
+ BOOL WaitForCompletion;
LRESULT Result = 0; //// Result could be trashed. ////
+ /* Notification messages and some internal messages sent from the subsystem must not block current
+ thread and therefore pass NULL as ThreadQueue. Callbacks also do not block */
+ WaitForCompletion = ((ThreadQueue) && (!CompletionCallback));
+
if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
{
DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
return STATUS_INSUFFICIENT_RESOURCES;
}
- KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
+ /* Initialize event if calling thread will wait on completion */
+ if (WaitForCompletion)
+ KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
ptirec = MessageQueue->Thread->Tcb.Win32Thread;
ASSERT(ThreadQueue != MessageQueue);
ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
Timeout.QuadPart = (LONGLONG) uTimeout * (LONGLONG) -10000;
- /* FIXME - increase reference counter of sender's message queue here */
-
Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
Message->Msg.lParam = lParam;
- Message->CompletionEvent = &CompletionEvent;
- Message->Result = &Result;
Message->lResult = 0;
Message->QS_Flags = 0;
- Message->SenderQueue = ThreadQueue;
- Message->CallBackSenderQueue = NULL;
- IntReferenceMessageQueue(ThreadQueue);
- Message->CompletionCallback = NULL;
- Message->CompletionCallbackContext = 0;
+
+ if (WaitForCompletion)
+ {
+ /* Normal SendMessage that will block until the Windows Procedure handles the message */
+ Message->SenderQueue = ThreadQueue;
+ Message->CompletionEvent = &CompletionEvent;
+ Message->Result = &Result;
+ }
+ else
+ {
+ /* Either a SendMessageCallback, Notify Message or Internal Message from Win32k */
+ Message->SenderQueue = NULL;
+ Message->CompletionEvent = NULL;
+ Message->Result = NULL;
+ }
+
+ if (CompletionCallback)
+ {
+ Message->CallBackSenderQueue = ThreadQueue;
+ }
+ else
+ {
+ Message->CallBackSenderQueue = NULL;
+ }
+
+ /* Reference the ThreadQueue if there was one. For normal messages
+ the thread is dereferenced when the messages is processed by windows procedure.
+ For callbacks it dereferenced once the callback message is processed and placed back
+ into the sending message queue */
+ if (ThreadQueue != NULL)
+ IntReferenceMessageQueue(ThreadQueue);
+
+ Message->CompletionCallback = CompletionCallback;
+ Message->CompletionCallbackContext = CompletionCallbackContext;
Message->HookMessage = HookMessage;
- Message->HasPackedLParam = FALSE;
-
+ Message->HasPackedLParam = HasPackedLParam;
+
+ if (HasPackedLParam)
+ {
+ ASSERT(Message->SenderQueue == NULL);
+ }
+
IntReferenceMessageQueue(MessageQueue);
- /* add it to the list of pending messages */
- InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
+ /* Add it to the list of pending messages if waiting on completion or if message is callback.
+ This is done for callbacks as if the Sender terminates it will set the CallBackSenderQueue member to NULL,
+ informing the windows procedure handling the message to discard the callback procedure */
+ if (ThreadQueue != NULL)
+ InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
/* queue it in the destination's message queue */
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
Message->QS_Flags = QS_SENDMESSAGE;
MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE);
+
+ /* If not waiting on completion, dereference the MessageQueue and return */
+ if (!WaitForCompletion)
+ {
+ IntDereferenceMessageQueue(MessageQueue);
+ return STATUS_SUCCESS;
+ }
/* we can't access the Message anymore since it could have already been deleted! */
@@ -854,7 +918,7 @@
* Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
* the window has the WS_EX_NOPARENTNOTIFY style.
*/
-static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
+void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
{
PWND pwndDesktop = UserGetWindowObject(IntGetDesktopWindow());
@@ -1466,8 +1530,8 @@
DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
- /* remove the message from the dispatching list if needed */
- if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+ /* remove the message from the dispatching list if there was a SenderQueue */
+ if (((CurrentSentMessage->SenderQueue) || (CurrentSentMessage->CallBackSenderQueue))
&& (CurrentSentMessage->DispatchingListEntry.Flink != NULL))
{
RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
@@ -1485,8 +1549,8 @@
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
}
- /* Only if it is not a no wait message */
- if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+ /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */
+ if (CurrentSentMessage->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(MessageQueue);
@@ -1525,8 +1589,8 @@
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
}
- /* Only if it is not a no wait message */
- if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+ /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */
+ if (CurrentSentMessage->SenderQueue)
{
/* dereference our and the sender's message queue */
IntDereferenceMessageQueue(MessageQueue);
Author: fireball
Date: Mon Apr 4 19:35:24 2011
New Revision: 51253
URL: http://svn.reactos.org/svn/reactos?rev=51253&view=rev
Log:
[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.
Modified:
trunk/reactos/dll/ntdll/ldr/ldrapi.c
trunk/reactos/dll/win32/kernel32/misc/ldr.c
trunk/reactos/include/ndk/ldrtypes.h
Modified: trunk/reactos/dll/ntdll/ldr/ldrapi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrapi.c?rev…
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/ldrapi.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ldr/ldrapi.c [iso-8859-1] Mon Apr 4 19:35:24 2011
@@ -15,9 +15,6 @@
/* GLOBALS *******************************************************************/
-#define LDR_LOCK_HELD 0x2
-#define LDR_LOCK_FREE 0x1
-
LONG LdrpLoaderLockAcquisitonCount;
/* FUNCTIONS *****************************************************************/
@@ -38,7 +35,7 @@
if (Flags & ~1)
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@@ -60,7 +57,7 @@
DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@@ -73,7 +70,7 @@
}
/* 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 */
RtlLeaveCriticalSection(&LdrpLoaderLock);
@@ -118,11 +115,11 @@
if (Cookie) *Cookie = 0;
/* 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))
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@@ -136,7 +133,7 @@
if (!Cookie)
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_3);
@@ -150,7 +147,7 @@
if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result))
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@@ -164,7 +161,7 @@
if (InInit) return STATUS_SUCCESS;
/* 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 */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
@@ -173,13 +170,13 @@
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{
/* It's locked */
- *Result = LDR_LOCK_HELD;
+ *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
goto Quickie;
}
else
{
/* It worked */
- *Result = LDR_LOCK_FREE;
+ *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
}
}
else
@@ -188,7 +185,7 @@
RtlEnterCriticalSection(&LdrpLoaderLock);
/* 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 */
@@ -209,13 +206,13 @@
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{
/* It's locked */
- *Result = LDR_LOCK_HELD;
+ *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
_SEH2_YIELD(return STATUS_SUCCESS);
}
else
{
/* It worked */
- *Result = LDR_LOCK_FREE;
+ *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
}
}
else
@@ -224,7 +221,7 @@
RtlEnterCriticalSection(&LdrpLoaderLock);
/* 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 */
Modified: trunk/reactos/dll/win32/kernel32/misc/ldr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/ld…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/ldr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/ldr.c [iso-8859-1] Mon Apr 4 19:35:24 2011
@@ -22,7 +22,7 @@
extern BOOLEAN InWindows;
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_CONTINUE 3
@@ -47,14 +47,14 @@
)
{
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 */
if (!phModule)
{
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 */
@@ -578,7 +578,7 @@
Peb = NtCurrentPeb ();
/* 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 */
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
@@ -615,7 +615,7 @@
} _SEH2_END
/* 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);
}
@@ -709,7 +709,8 @@
hModule = GetModuleHandleForUnicodeString(&ModuleNameU);
if (!hModule)
{
- // FIXME: Status?!
+ /* Last error is already set, so just return failure by setting status */
+ Status = STATUS_DLL_NOT_FOUND;
goto quickie;
}
}
@@ -737,6 +738,10 @@
hModule);
}
+ /* Set last error in case of failure */
+ if (!NT_SUCCESS(Status))
+ SetLastErrorByStatus(Status);
+
quickie:
/* Unlock loader lock if it was acquired */
if (!NoLock)
@@ -744,10 +749,6 @@
Status2 = LdrUnlockLoaderLock(0, Cookie);
ASSERT(NT_SUCCESS(Status2));
}
-
- /* Set last error in case of failure */
- if (!NT_SUCCESS(Status))
- SetLastErrorByStatus(Status);
/* Set the module handle to the caller */
if (phModule) *phModule = hModule;
@@ -827,7 +828,7 @@
dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule);
/* 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 (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
@@ -855,13 +856,14 @@
{
PUNICODE_STRING lpModuleNameW;
DWORD dwValid;
- BOOL Ret;
+ BOOL Ret = FALSE;
+ NTSTATUS Status;
/* Validate parameters */
dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, (LPCWSTR)lpModuleName, phModule);
/* 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 (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
@@ -869,10 +871,11 @@
/* Check if we don't need to convert the name */
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
{
- /* Call the W version of the API without conversion */
- Ret = GetModuleHandleExW(dwFlags,
- (LPCWSTR)lpModuleName,
- phModule);
+ /* Call the extended version of the API without conversion */
+ Status = BasepGetModuleHandleExW(FALSE,
+ dwFlags,
+ (LPCWSTR)lpModuleName,
+ phModule);
}
else
{
@@ -882,11 +885,16 @@
/* Return FALSE if conversion failed */
if (!lpModuleNameW) return FALSE;
- /* Call the W version of the API */
- Ret = GetModuleHandleExW(dwFlags,
- lpModuleNameW->Buffer,
- phModule);
- }
+ /* Call the extended version of the API */
+ Status = BasepGetModuleHandleExW(FALSE,
+ dwFlags,
+ lpModuleNameW->Buffer,
+ phModule);
+ }
+
+ /* If result was successful - return true */
+ if (NT_SUCCESS(Status))
+ Ret = TRUE;
/* Return result */
return Ret;
Modified: trunk/reactos/include/ndk/ldrtypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ldrtypes.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/ldrtypes.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/ldrtypes.h [iso-8859-1] Mon Apr 4 19:35:24 2011
@@ -71,8 +71,12 @@
//
// LdrLockLoaderLock Flags
//
-#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS 0x00000001
-#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002
+#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001
+#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!