diff options
Diffstat (limited to '')
-rw-r--r-- | src/dutil/monutil.cpp | 205 |
1 files changed, 110 insertions, 95 deletions
diff --git a/src/dutil/monutil.cpp b/src/dutil/monutil.cpp index 6f280538..6a7f0596 100644 --- a/src/dutil/monutil.cpp +++ b/src/dutil/monutil.cpp | |||
@@ -2,6 +2,21 @@ | |||
2 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | |||
6 | // Exit macros | ||
7 | #define MonExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_MONUTIL, x, s, __VA_ARGS__) | ||
8 | #define MonExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_MONUTIL, x, s, __VA_ARGS__) | ||
9 | #define MonExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_MONUTIL, x, s, __VA_ARGS__) | ||
10 | #define MonExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_MONUTIL, x, s, __VA_ARGS__) | ||
11 | #define MonExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_MONUTIL, x, s, __VA_ARGS__) | ||
12 | #define MonExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_MONUTIL, x, s, __VA_ARGS__) | ||
13 | #define MonExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_MONUTIL, p, x, e, s, __VA_ARGS__) | ||
14 | #define MonExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_MONUTIL, p, x, s, __VA_ARGS__) | ||
15 | #define MonExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_MONUTIL, p, x, e, s, __VA_ARGS__) | ||
16 | #define MonExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_MONUTIL, p, x, s, __VA_ARGS__) | ||
17 | #define MonExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_MONUTIL, e, x, s, __VA_ARGS__) | ||
18 | #define MonExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_MONUTIL, g, x, s, __VA_ARGS__) | ||
19 | |||
5 | const int MON_THREAD_GROWTH = 5; | 20 | const int MON_THREAD_GROWTH = 5; |
6 | const int MON_ARRAY_GROWTH = 40; | 21 | const int MON_ARRAY_GROWTH = 40; |
7 | const int MON_MAX_MONITORS_PER_THREAD = 63; | 22 | const int MON_MAX_MONITORS_PER_THREAD = 63; |
@@ -218,10 +233,10 @@ static void MonRequestDestroy( | |||
218 | __in MON_REQUEST *pRequest | 233 | __in MON_REQUEST *pRequest |
219 | ); | 234 | ); |
220 | static void MonAddMessageDestroy( | 235 | static void MonAddMessageDestroy( |
221 | __in MON_ADD_MESSAGE *pMessage | 236 | __in_opt MON_ADD_MESSAGE *pMessage |
222 | ); | 237 | ); |
223 | static void MonRemoveMessageDestroy( | 238 | static void MonRemoveMessageDestroy( |
224 | __in MON_REMOVE_MESSAGE *pMessage | 239 | __in_opt MON_REMOVE_MESSAGE *pMessage |
225 | ); | 240 | ); |
226 | static BOOL GetRecursiveFlag( | 241 | static BOOL GetRecursiveFlag( |
227 | __in MON_REQUEST *pRequest, | 242 | __in MON_REQUEST *pRequest, |
@@ -262,7 +277,7 @@ static HRESULT UpdateWaitStatus( | |||
262 | __in HRESULT hrNewStatus, | 277 | __in HRESULT hrNewStatus, |
263 | __inout MON_WAITER_CONTEXT *pWaiterContext, | 278 | __inout MON_WAITER_CONTEXT *pWaiterContext, |
264 | __in DWORD dwRequestIndex, | 279 | __in DWORD dwRequestIndex, |
265 | __out DWORD *pdwNewRequestIndex | 280 | __out_opt DWORD *pdwNewRequestIndex |
266 | ); | 281 | ); |
267 | 282 | ||
268 | extern "C" HRESULT DAPI MonCreate( | 283 | extern "C" HRESULT DAPI MonCreate( |
@@ -277,11 +292,11 @@ extern "C" HRESULT DAPI MonCreate( | |||
277 | HRESULT hr = S_OK; | 292 | HRESULT hr = S_OK; |
278 | DWORD dwRetries = MON_THREAD_INIT_RETRIES; | 293 | DWORD dwRetries = MON_THREAD_INIT_RETRIES; |
279 | 294 | ||
280 | ExitOnNull(pHandle, hr, E_INVALIDARG, "Pointer to handle not specified while creating monitor"); | 295 | MonExitOnNull(pHandle, hr, E_INVALIDARG, "Pointer to handle not specified while creating monitor"); |
281 | 296 | ||
282 | // Allocate the struct | 297 | // Allocate the struct |
283 | *pHandle = static_cast<MON_HANDLE>(MemAlloc(sizeof(MON_STRUCT), TRUE)); | 298 | *pHandle = static_cast<MON_HANDLE>(MemAlloc(sizeof(MON_STRUCT), TRUE)); |
284 | ExitOnNull(*pHandle, hr, E_OUTOFMEMORY, "Failed to allocate monitor object"); | 299 | MonExitOnNull(*pHandle, hr, E_OUTOFMEMORY, "Failed to allocate monitor object"); |
285 | 300 | ||
286 | MON_STRUCT *pm = static_cast<MON_STRUCT *>(*pHandle); | 301 | MON_STRUCT *pm = static_cast<MON_STRUCT *>(*pHandle); |
287 | 302 | ||
@@ -294,7 +309,7 @@ extern "C" HRESULT DAPI MonCreate( | |||
294 | pm->hCoordinatorThread = ::CreateThread(NULL, 0, CoordinatorThread, pm, 0, &pm->dwCoordinatorThreadId); | 309 | pm->hCoordinatorThread = ::CreateThread(NULL, 0, CoordinatorThread, pm, 0, &pm->dwCoordinatorThreadId); |
295 | if (!pm->hCoordinatorThread) | 310 | if (!pm->hCoordinatorThread) |
296 | { | 311 | { |
297 | ExitWithLastError(hr, "Failed to create waiter thread."); | 312 | MonExitWithLastError(hr, "Failed to create waiter thread."); |
298 | } | 313 | } |
299 | 314 | ||
300 | // Ensure the created thread initializes its message queue. It does this first thing, so if it doesn't within 10 seconds, there must be a huge problem. | 315 | // Ensure the created thread initializes its message queue. It does this first thing, so if it doesn't within 10 seconds, there must be a huge problem. |
@@ -307,7 +322,7 @@ extern "C" HRESULT DAPI MonCreate( | |||
307 | if (0 == dwRetries) | 322 | if (0 == dwRetries) |
308 | { | 323 | { |
309 | hr = E_UNEXPECTED; | 324 | hr = E_UNEXPECTED; |
310 | ExitOnFailure(hr, "Waiter thread apparently never initialized its message queue."); | 325 | MonExitOnFailure(hr, "Waiter thread apparently never initialized its message queue."); |
311 | } | 326 | } |
312 | 327 | ||
313 | LExit: | 328 | LExit: |
@@ -329,13 +344,13 @@ extern "C" HRESULT DAPI MonAddDirectory( | |||
329 | MON_ADD_MESSAGE *pMessage = NULL; | 344 | MON_ADD_MESSAGE *pMessage = NULL; |
330 | 345 | ||
331 | hr = StrAllocString(&sczOriginalPathRequest, wzDirectory, 0); | 346 | hr = StrAllocString(&sczOriginalPathRequest, wzDirectory, 0); |
332 | ExitOnFailure(hr, "Failed to convert directory string to UNC path"); | 347 | MonExitOnFailure(hr, "Failed to convert directory string to UNC path"); |
333 | 348 | ||
334 | hr = PathBackslashTerminate(&sczOriginalPathRequest); | 349 | hr = PathBackslashTerminate(&sczOriginalPathRequest); |
335 | ExitOnFailure(hr, "Failed to ensure directory ends in backslash"); | 350 | MonExitOnFailure(hr, "Failed to ensure directory ends in backslash"); |
336 | 351 | ||
337 | pMessage = reinterpret_cast<MON_ADD_MESSAGE *>(MemAlloc(sizeof(MON_ADD_MESSAGE), TRUE)); | 352 | pMessage = reinterpret_cast<MON_ADD_MESSAGE *>(MemAlloc(sizeof(MON_ADD_MESSAGE), TRUE)); |
338 | ExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); | 353 | MonExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); |
339 | 354 | ||
340 | if (sczOriginalPathRequest[0] == L'\\' && sczOriginalPathRequest[1] == L'\\') | 355 | if (sczOriginalPathRequest[0] == L'\\' && sczOriginalPathRequest[1] == L'\\') |
341 | { | 356 | { |
@@ -356,7 +371,7 @@ extern "C" HRESULT DAPI MonAddDirectory( | |||
356 | hr = S_OK; | 371 | hr = S_OK; |
357 | 372 | ||
358 | hr = StrAllocString(&sczDirectory, sczOriginalPathRequest, 0); | 373 | hr = StrAllocString(&sczDirectory, sczOriginalPathRequest, 0); |
359 | ExitOnFailure(hr, "Failed to copy original path request: %ls", sczOriginalPathRequest); | 374 | MonExitOnFailure(hr, "Failed to copy original path request: %ls", sczOriginalPathRequest); |
360 | } | 375 | } |
361 | 376 | ||
362 | pMessage->handle = INVALID_HANDLE_VALUE; | 377 | pMessage->handle = INVALID_HANDLE_VALUE; |
@@ -369,14 +384,14 @@ extern "C" HRESULT DAPI MonAddDirectory( | |||
369 | sczOriginalPathRequest = NULL; | 384 | sczOriginalPathRequest = NULL; |
370 | 385 | ||
371 | hr = PathGetHierarchyArray(sczDirectory, &pMessage->request.rgsczPathHierarchy, reinterpret_cast<LPUINT>(&pMessage->request.cPathHierarchy)); | 386 | hr = PathGetHierarchyArray(sczDirectory, &pMessage->request.rgsczPathHierarchy, reinterpret_cast<LPUINT>(&pMessage->request.cPathHierarchy)); |
372 | ExitOnFailure(hr, "Failed to get hierarchy array for path %ls", sczDirectory); | 387 | MonExitOnFailure(hr, "Failed to get hierarchy array for path %ls", sczDirectory); |
373 | 388 | ||
374 | if (0 < pMessage->request.cPathHierarchy) | 389 | if (0 < pMessage->request.cPathHierarchy) |
375 | { | 390 | { |
376 | pMessage->request.hrStatus = InitiateWait(&pMessage->request, &pMessage->handle); | 391 | pMessage->request.hrStatus = InitiateWait(&pMessage->request, &pMessage->handle); |
377 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_ADD, reinterpret_cast<WPARAM>(pMessage), 0)) | 392 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_ADD, reinterpret_cast<WPARAM>(pMessage), 0)) |
378 | { | 393 | { |
379 | ExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for path %ls", sczDirectory); | 394 | MonExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for path %ls", sczDirectory); |
380 | } | 395 | } |
381 | pMessage = NULL; | 396 | pMessage = NULL; |
382 | } | 397 | } |
@@ -405,16 +420,16 @@ extern "C" HRESULT DAPI MonAddRegKey( | |||
405 | MON_ADD_MESSAGE *pMessage = NULL; | 420 | MON_ADD_MESSAGE *pMessage = NULL; |
406 | 421 | ||
407 | hr = StrAllocString(&sczSubKey, wzSubKey, 0); | 422 | hr = StrAllocString(&sczSubKey, wzSubKey, 0); |
408 | ExitOnFailure(hr, "Failed to copy subkey string"); | 423 | MonExitOnFailure(hr, "Failed to copy subkey string"); |
409 | 424 | ||
410 | hr = PathBackslashTerminate(&sczSubKey); | 425 | hr = PathBackslashTerminate(&sczSubKey); |
411 | ExitOnFailure(hr, "Failed to ensure subkey path ends in backslash"); | 426 | MonExitOnFailure(hr, "Failed to ensure subkey path ends in backslash"); |
412 | 427 | ||
413 | pMessage = reinterpret_cast<MON_ADD_MESSAGE *>(MemAlloc(sizeof(MON_ADD_MESSAGE), TRUE)); | 428 | pMessage = reinterpret_cast<MON_ADD_MESSAGE *>(MemAlloc(sizeof(MON_ADD_MESSAGE), TRUE)); |
414 | ExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); | 429 | MonExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); |
415 | 430 | ||
416 | pMessage->handle = ::CreateEventW(NULL, TRUE, FALSE, NULL); | 431 | pMessage->handle = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
417 | ExitOnNullWithLastError(pMessage->handle, hr, "Failed to create anonymous event for regkey monitor"); | 432 | MonExitOnNullWithLastError(pMessage->handle, hr, "Failed to create anonymous event for regkey monitor"); |
418 | 433 | ||
419 | pMessage->request.type = MON_REGKEY; | 434 | pMessage->request.type = MON_REGKEY; |
420 | pMessage->request.regkey.hkRoot = hkRoot; | 435 | pMessage->request.regkey.hkRoot = hkRoot; |
@@ -425,16 +440,16 @@ extern "C" HRESULT DAPI MonAddRegKey( | |||
425 | pMessage->request.pvContext = pvRegKeyContext; | 440 | pMessage->request.pvContext = pvRegKeyContext; |
426 | 441 | ||
427 | hr = PathGetHierarchyArray(sczSubKey, &pMessage->request.rgsczPathHierarchy, reinterpret_cast<LPUINT>(&pMessage->request.cPathHierarchy)); | 442 | hr = PathGetHierarchyArray(sczSubKey, &pMessage->request.rgsczPathHierarchy, reinterpret_cast<LPUINT>(&pMessage->request.cPathHierarchy)); |
428 | ExitOnFailure(hr, "Failed to get hierarchy array for subkey %ls", sczSubKey); | 443 | MonExitOnFailure(hr, "Failed to get hierarchy array for subkey %ls", sczSubKey); |
429 | 444 | ||
430 | if (0 < pMessage->request.cPathHierarchy) | 445 | if (0 < pMessage->request.cPathHierarchy) |
431 | { | 446 | { |
432 | pMessage->request.hrStatus = InitiateWait(&pMessage->request, &pMessage->handle); | 447 | pMessage->request.hrStatus = InitiateWait(&pMessage->request, &pMessage->handle); |
433 | ExitOnFailure(hr, "Failed to initiate wait"); | 448 | MonExitOnFailure(hr, "Failed to initiate wait"); |
434 | 449 | ||
435 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_ADD, reinterpret_cast<WPARAM>(pMessage), 0)) | 450 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_ADD, reinterpret_cast<WPARAM>(pMessage), 0)) |
436 | { | 451 | { |
437 | ExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for regkey %ls", sczSubKey); | 452 | MonExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for regkey %ls", sczSubKey); |
438 | } | 453 | } |
439 | pMessage = NULL; | 454 | pMessage = NULL; |
440 | } | 455 | } |
@@ -458,23 +473,23 @@ extern "C" HRESULT DAPI MonRemoveDirectory( | |||
458 | MON_REMOVE_MESSAGE *pMessage = NULL; | 473 | MON_REMOVE_MESSAGE *pMessage = NULL; |
459 | 474 | ||
460 | hr = StrAllocString(&sczDirectory, wzDirectory, 0); | 475 | hr = StrAllocString(&sczDirectory, wzDirectory, 0); |
461 | ExitOnFailure(hr, "Failed to copy directory string"); | 476 | MonExitOnFailure(hr, "Failed to copy directory string"); |
462 | 477 | ||
463 | hr = PathBackslashTerminate(&sczDirectory); | 478 | hr = PathBackslashTerminate(&sczDirectory); |
464 | ExitOnFailure(hr, "Failed to ensure directory ends in backslash"); | 479 | MonExitOnFailure(hr, "Failed to ensure directory ends in backslash"); |
465 | 480 | ||
466 | pMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(MemAlloc(sizeof(MON_REMOVE_MESSAGE), TRUE)); | 481 | pMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(MemAlloc(sizeof(MON_REMOVE_MESSAGE), TRUE)); |
467 | ExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); | 482 | MonExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); |
468 | 483 | ||
469 | pMessage->type = MON_DIRECTORY; | 484 | pMessage->type = MON_DIRECTORY; |
470 | pMessage->fRecursive = fRecursive; | 485 | pMessage->fRecursive = fRecursive; |
471 | 486 | ||
472 | hr = StrAllocString(&pMessage->directory.sczDirectory, sczDirectory, 0); | 487 | hr = StrAllocString(&pMessage->directory.sczDirectory, sczDirectory, 0); |
473 | ExitOnFailure(hr, "Failed to allocate copy of directory string"); | 488 | MonExitOnFailure(hr, "Failed to allocate copy of directory string"); |
474 | 489 | ||
475 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_REMOVE, reinterpret_cast<WPARAM>(pMessage), 0)) | 490 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_REMOVE, reinterpret_cast<WPARAM>(pMessage), 0)) |
476 | { | 491 | { |
477 | ExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for path %ls", sczDirectory); | 492 | MonExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for path %ls", sczDirectory); |
478 | } | 493 | } |
479 | pMessage = NULL; | 494 | pMessage = NULL; |
480 | 495 | ||
@@ -498,13 +513,13 @@ extern "C" HRESULT DAPI MonRemoveRegKey( | |||
498 | MON_REMOVE_MESSAGE *pMessage = NULL; | 513 | MON_REMOVE_MESSAGE *pMessage = NULL; |
499 | 514 | ||
500 | hr = StrAllocString(&sczSubKey, wzSubKey, 0); | 515 | hr = StrAllocString(&sczSubKey, wzSubKey, 0); |
501 | ExitOnFailure(hr, "Failed to copy subkey string"); | 516 | MonExitOnFailure(hr, "Failed to copy subkey string"); |
502 | 517 | ||
503 | hr = PathBackslashTerminate(&sczSubKey); | 518 | hr = PathBackslashTerminate(&sczSubKey); |
504 | ExitOnFailure(hr, "Failed to ensure subkey path ends in backslash"); | 519 | MonExitOnFailure(hr, "Failed to ensure subkey path ends in backslash"); |
505 | 520 | ||
506 | pMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(MemAlloc(sizeof(MON_REMOVE_MESSAGE), TRUE)); | 521 | pMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(MemAlloc(sizeof(MON_REMOVE_MESSAGE), TRUE)); |
507 | ExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); | 522 | MonExitOnNull(pMessage, hr, E_OUTOFMEMORY, "Failed to allocate memory for message"); |
508 | 523 | ||
509 | pMessage->type = MON_REGKEY; | 524 | pMessage->type = MON_REGKEY; |
510 | pMessage->regkey.hkRoot = hkRoot; | 525 | pMessage->regkey.hkRoot = hkRoot; |
@@ -512,11 +527,11 @@ extern "C" HRESULT DAPI MonRemoveRegKey( | |||
512 | pMessage->fRecursive = fRecursive; | 527 | pMessage->fRecursive = fRecursive; |
513 | 528 | ||
514 | hr = StrAllocString(&pMessage->regkey.sczSubKey, sczSubKey, 0); | 529 | hr = StrAllocString(&pMessage->regkey.sczSubKey, sczSubKey, 0); |
515 | ExitOnFailure(hr, "Failed to allocate copy of directory string"); | 530 | MonExitOnFailure(hr, "Failed to allocate copy of directory string"); |
516 | 531 | ||
517 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_REMOVE, reinterpret_cast<WPARAM>(pMessage), 0)) | 532 | if (!::PostThreadMessageW(pm->dwCoordinatorThreadId, MON_MESSAGE_REMOVE, reinterpret_cast<WPARAM>(pMessage), 0)) |
518 | { | 533 | { |
519 | ExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for path %ls", sczSubKey); | 534 | MonExitWithLastError(hr, "Failed to send message to worker thread to add directory wait for path %ls", sczSubKey); |
520 | } | 535 | } |
521 | pMessage = NULL; | 536 | pMessage = NULL; |
522 | 537 | ||
@@ -543,7 +558,7 @@ extern "C" void DAPI MonDestroy( | |||
543 | // It already halted, or doesn't exist for some other reason, so let's just ignore it and clean up | 558 | // It already halted, or doesn't exist for some other reason, so let's just ignore it and clean up |
544 | er = ERROR_SUCCESS; | 559 | er = ERROR_SUCCESS; |
545 | } | 560 | } |
546 | ExitOnWin32Error(er, hr, "Failed to send message to background thread to halt"); | 561 | MonExitOnWin32Error(er, hr, "Failed to send message to background thread to halt"); |
547 | } | 562 | } |
548 | 563 | ||
549 | if (pm->hCoordinatorThread) | 564 | if (pm->hCoordinatorThread) |
@@ -577,10 +592,10 @@ static void MonRequestDestroy( | |||
577 | } | 592 | } |
578 | 593 | ||
579 | static void MonAddMessageDestroy( | 594 | static void MonAddMessageDestroy( |
580 | __in MON_ADD_MESSAGE *pMessage | 595 | __in_opt MON_ADD_MESSAGE *pMessage |
581 | ) | 596 | ) |
582 | { | 597 | { |
583 | if (NULL != pMessage) | 598 | if (pMessage) |
584 | { | 599 | { |
585 | MonRequestDestroy(&pMessage->request); | 600 | MonRequestDestroy(&pMessage->request); |
586 | if (MON_DIRECTORY == pMessage->request.type && INVALID_HANDLE_VALUE != pMessage->handle) | 601 | if (MON_DIRECTORY == pMessage->request.type && INVALID_HANDLE_VALUE != pMessage->handle) |
@@ -597,10 +612,10 @@ static void MonAddMessageDestroy( | |||
597 | } | 612 | } |
598 | 613 | ||
599 | static void MonRemoveMessageDestroy( | 614 | static void MonRemoveMessageDestroy( |
600 | __in MON_REMOVE_MESSAGE *pMessage | 615 | __in_opt MON_REMOVE_MESSAGE *pMessage |
601 | ) | 616 | ) |
602 | { | 617 | { |
603 | if (NULL != pMessage) | 618 | if (pMessage) |
604 | { | 619 | { |
605 | switch (pMessage->type) | 620 | switch (pMessage->type) |
606 | { | 621 | { |
@@ -642,17 +657,17 @@ static DWORD WINAPI CoordinatorThread( | |||
642 | pm->fCoordinatorThreadMessageQueueInitialized = TRUE; | 657 | pm->fCoordinatorThreadMessageQueueInitialized = TRUE; |
643 | 658 | ||
644 | hr = CreateMonWindow(pm, &pm->hwnd); | 659 | hr = CreateMonWindow(pm, &pm->hwnd); |
645 | ExitOnFailure(hr, "Failed to create window for status update thread"); | 660 | MonExitOnFailure(hr, "Failed to create window for status update thread"); |
646 | 661 | ||
647 | ::WSAStartup(MAKEWORD(2, 2), &wsaData); | 662 | ::WSAStartup(MAKEWORD(2, 2), &wsaData); |
648 | 663 | ||
649 | hr = WaitForNetworkChanges(&hMonitor, pm); | 664 | hr = WaitForNetworkChanges(&hMonitor, pm); |
650 | ExitOnFailure(hr, "Failed to wait for network changes"); | 665 | MonExitOnFailure(hr, "Failed to wait for network changes"); |
651 | 666 | ||
652 | uTimerSuccessfulNetworkRetry = ::SetTimer(NULL, 1, MON_THREAD_NETWORK_SUCCESSFUL_RETRY_IN_MS, NULL); | 667 | uTimerSuccessfulNetworkRetry = ::SetTimer(NULL, 1, MON_THREAD_NETWORK_SUCCESSFUL_RETRY_IN_MS, NULL); |
653 | if (0 == uTimerSuccessfulNetworkRetry) | 668 | if (0 == uTimerSuccessfulNetworkRetry) |
654 | { | 669 | { |
655 | ExitWithLastError(hr, "Failed to set timer for network successful retry"); | 670 | MonExitWithLastError(hr, "Failed to set timer for network successful retry"); |
656 | } | 671 | } |
657 | 672 | ||
658 | while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) | 673 | while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) |
@@ -660,7 +675,7 @@ static DWORD WINAPI CoordinatorThread( | |||
660 | if (-1 == fRet) | 675 | if (-1 == fRet) |
661 | { | 676 | { |
662 | hr = E_UNEXPECTED; | 677 | hr = E_UNEXPECTED; |
663 | ExitOnRootFailure(hr, "Unexpected return value from message pump."); | 678 | MonExitOnRootFailure(hr, "Unexpected return value from message pump."); |
664 | } | 679 | } |
665 | else | 680 | else |
666 | { | 681 | { |
@@ -684,12 +699,12 @@ static DWORD WINAPI CoordinatorThread( | |||
684 | else | 699 | else |
685 | { | 700 | { |
686 | hr = MemEnsureArraySize(reinterpret_cast<void **>(&pm->rgWaiterThreads), pm->cWaiterThreads + 1, sizeof(MON_WAITER_INFO), MON_THREAD_GROWTH); | 701 | hr = MemEnsureArraySize(reinterpret_cast<void **>(&pm->rgWaiterThreads), pm->cWaiterThreads + 1, sizeof(MON_WAITER_INFO), MON_THREAD_GROWTH); |
687 | ExitOnFailure(hr, "Failed to grow waiter thread array size"); | 702 | MonExitOnFailure(hr, "Failed to grow waiter thread array size"); |
688 | ++pm->cWaiterThreads; | 703 | ++pm->cWaiterThreads; |
689 | 704 | ||
690 | dwThreadIndex = pm->cWaiterThreads - 1; | 705 | dwThreadIndex = pm->cWaiterThreads - 1; |
691 | pm->rgWaiterThreads[dwThreadIndex].pWaiterContext = reinterpret_cast<MON_WAITER_CONTEXT*>(MemAlloc(sizeof(MON_WAITER_CONTEXT), TRUE)); | 706 | pm->rgWaiterThreads[dwThreadIndex].pWaiterContext = reinterpret_cast<MON_WAITER_CONTEXT*>(MemAlloc(sizeof(MON_WAITER_CONTEXT), TRUE)); |
692 | ExitOnNull(pm->rgWaiterThreads[dwThreadIndex].pWaiterContext, hr, E_OUTOFMEMORY, "Failed to allocate waiter context struct"); | 707 | MonExitOnNull(pm->rgWaiterThreads[dwThreadIndex].pWaiterContext, hr, E_OUTOFMEMORY, "Failed to allocate waiter context struct"); |
693 | pWaiterContext = pm->rgWaiterThreads[dwThreadIndex].pWaiterContext; | 708 | pWaiterContext = pm->rgWaiterThreads[dwThreadIndex].pWaiterContext; |
694 | pWaiterContext->dwCoordinatorThreadId = ::GetCurrentThreadId(); | 709 | pWaiterContext->dwCoordinatorThreadId = ::GetCurrentThreadId(); |
695 | pWaiterContext->vpfMonGeneral = pm->vpfMonGeneral; | 710 | pWaiterContext->vpfMonGeneral = pm->vpfMonGeneral; |
@@ -698,16 +713,16 @@ static DWORD WINAPI CoordinatorThread( | |||
698 | pWaiterContext->pvContext = pm->pvContext; | 713 | pWaiterContext->pvContext = pm->pvContext; |
699 | 714 | ||
700 | hr = MemEnsureArraySize(reinterpret_cast<void **>(&pWaiterContext->rgHandles), MON_MAX_MONITORS_PER_THREAD + 1, sizeof(HANDLE), 0); | 715 | hr = MemEnsureArraySize(reinterpret_cast<void **>(&pWaiterContext->rgHandles), MON_MAX_MONITORS_PER_THREAD + 1, sizeof(HANDLE), 0); |
701 | ExitOnFailure(hr, "Failed to allocate first handle"); | 716 | MonExitOnFailure(hr, "Failed to allocate first handle"); |
702 | pWaiterContext->cHandles = 1; | 717 | pWaiterContext->cHandles = 1; |
703 | 718 | ||
704 | pWaiterContext->rgHandles[0] = ::CreateEventW(NULL, FALSE, FALSE, NULL); | 719 | pWaiterContext->rgHandles[0] = ::CreateEventW(NULL, FALSE, FALSE, NULL); |
705 | ExitOnNullWithLastError(pWaiterContext->rgHandles[0], hr, "Failed to create general event"); | 720 | MonExitOnNullWithLastError(pWaiterContext->rgHandles[0], hr, "Failed to create general event"); |
706 | 721 | ||
707 | pWaiterContext->hWaiterThread = ::CreateThread(NULL, 0, WaiterThread, pWaiterContext, 0, &pWaiterContext->dwWaiterThreadId); | 722 | pWaiterContext->hWaiterThread = ::CreateThread(NULL, 0, WaiterThread, pWaiterContext, 0, &pWaiterContext->dwWaiterThreadId); |
708 | if (!pWaiterContext->hWaiterThread) | 723 | if (!pWaiterContext->hWaiterThread) |
709 | { | 724 | { |
710 | ExitWithLastError(hr, "Failed to create waiter thread."); | 725 | MonExitWithLastError(hr, "Failed to create waiter thread."); |
711 | } | 726 | } |
712 | 727 | ||
713 | dwRetries = MON_THREAD_INIT_RETRIES; | 728 | dwRetries = MON_THREAD_INIT_RETRIES; |
@@ -720,19 +735,19 @@ static DWORD WINAPI CoordinatorThread( | |||
720 | if (0 == dwRetries) | 735 | if (0 == dwRetries) |
721 | { | 736 | { |
722 | hr = E_UNEXPECTED; | 737 | hr = E_UNEXPECTED; |
723 | ExitOnFailure(hr, "Waiter thread apparently never initialized its message queue."); | 738 | MonExitOnFailure(hr, "Waiter thread apparently never initialized its message queue."); |
724 | } | 739 | } |
725 | } | 740 | } |
726 | 741 | ||
727 | ++pm->rgWaiterThreads[dwThreadIndex].cMonitorCount; | 742 | ++pm->rgWaiterThreads[dwThreadIndex].cMonitorCount; |
728 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_ADD, msg.wParam, 0)) | 743 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_ADD, msg.wParam, 0)) |
729 | { | 744 | { |
730 | ExitWithLastError(hr, "Failed to send message to waiter thread to add monitor"); | 745 | MonExitWithLastError(hr, "Failed to send message to waiter thread to add monitor"); |
731 | } | 746 | } |
732 | 747 | ||
733 | if (!::SetEvent(pWaiterContext->rgHandles[0])) | 748 | if (!::SetEvent(pWaiterContext->rgHandles[0])) |
734 | { | 749 | { |
735 | ExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming message"); | 750 | MonExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming message"); |
736 | } | 751 | } |
737 | break; | 752 | break; |
738 | 753 | ||
@@ -746,17 +761,17 @@ static DWORD WINAPI CoordinatorThread( | |||
746 | pRemoveMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(msg.wParam); | 761 | pRemoveMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(msg.wParam); |
747 | 762 | ||
748 | hr = DuplicateRemoveMessage(pRemoveMessage, &pTempRemoveMessage); | 763 | hr = DuplicateRemoveMessage(pRemoveMessage, &pTempRemoveMessage); |
749 | ExitOnFailure(hr, "Failed to duplicate remove message"); | 764 | MonExitOnFailure(hr, "Failed to duplicate remove message"); |
750 | 765 | ||
751 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_REMOVE, reinterpret_cast<WPARAM>(pTempRemoveMessage), msg.lParam)) | 766 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_REMOVE, reinterpret_cast<WPARAM>(pTempRemoveMessage), msg.lParam)) |
752 | { | 767 | { |
753 | ExitWithLastError(hr, "Failed to send message to waiter thread to add monitor"); | 768 | MonExitWithLastError(hr, "Failed to send message to waiter thread to add monitor"); |
754 | } | 769 | } |
755 | pTempRemoveMessage = NULL; | 770 | pTempRemoveMessage = NULL; |
756 | 771 | ||
757 | if (!::SetEvent(pWaiterContext->rgHandles[0])) | 772 | if (!::SetEvent(pWaiterContext->rgHandles[0])) |
758 | { | 773 | { |
759 | ExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming remove message"); | 774 | MonExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming remove message"); |
760 | } | 775 | } |
761 | } | 776 | } |
762 | MonRemoveMessageDestroy(pRemoveMessage); | 777 | MonRemoveMessageDestroy(pRemoveMessage); |
@@ -774,7 +789,7 @@ static DWORD WINAPI CoordinatorThread( | |||
774 | { | 789 | { |
775 | if (!::PostThreadMessageW(pm->rgWaiterThreads[i].pWaiterContext->dwWaiterThreadId, MON_MESSAGE_STOP, msg.wParam, msg.lParam)) | 790 | if (!::PostThreadMessageW(pm->rgWaiterThreads[i].pWaiterContext->dwWaiterThreadId, MON_MESSAGE_STOP, msg.wParam, msg.lParam)) |
776 | { | 791 | { |
777 | ExitWithLastError(hr, "Failed to send message to waiter thread to stop"); | 792 | MonExitWithLastError(hr, "Failed to send message to waiter thread to stop"); |
778 | } | 793 | } |
779 | MemRemoveFromArray(reinterpret_cast<LPVOID>(pm->rgWaiterThreads), i, 1, pm->cWaiterThreads, sizeof(MON_WAITER_INFO), TRUE); | 794 | MemRemoveFromArray(reinterpret_cast<LPVOID>(pm->rgWaiterThreads), i, 1, pm->cWaiterThreads, sizeof(MON_WAITER_INFO), TRUE); |
780 | --pm->cWaiterThreads; | 795 | --pm->cWaiterThreads; |
@@ -790,7 +805,7 @@ static DWORD WINAPI CoordinatorThread( | |||
790 | uTimerFailedNetworkRetry = ::SetTimer(NULL, uTimerSuccessfulNetworkRetry + 1, MON_THREAD_NETWORK_FAIL_RETRY_IN_MS, NULL); | 805 | uTimerFailedNetworkRetry = ::SetTimer(NULL, uTimerSuccessfulNetworkRetry + 1, MON_THREAD_NETWORK_FAIL_RETRY_IN_MS, NULL); |
791 | if (0 == uTimerFailedNetworkRetry) | 806 | if (0 == uTimerFailedNetworkRetry) |
792 | { | 807 | { |
793 | ExitWithLastError(hr, "Failed to set timer for network fail retry"); | 808 | MonExitWithLastError(hr, "Failed to set timer for network fail retry"); |
794 | } | 809 | } |
795 | } | 810 | } |
796 | ++dwFailingNetworkWaits; | 811 | ++dwFailingNetworkWaits; |
@@ -802,7 +817,7 @@ static DWORD WINAPI CoordinatorThread( | |||
802 | { | 817 | { |
803 | if (!::KillTimer(NULL, uTimerFailedNetworkRetry)) | 818 | if (!::KillTimer(NULL, uTimerFailedNetworkRetry)) |
804 | { | 819 | { |
805 | ExitWithLastError(hr, "Failed to kill timer for network fail retry"); | 820 | MonExitWithLastError(hr, "Failed to kill timer for network fail retry"); |
806 | } | 821 | } |
807 | uTimerFailedNetworkRetry = 0; | 822 | uTimerFailedNetworkRetry = 0; |
808 | } | 823 | } |
@@ -810,7 +825,7 @@ static DWORD WINAPI CoordinatorThread( | |||
810 | 825 | ||
811 | case MON_MESSAGE_NETWORK_STATUS_UPDATE: | 826 | case MON_MESSAGE_NETWORK_STATUS_UPDATE: |
812 | hr = WaitForNetworkChanges(&hMonitor, pm); | 827 | hr = WaitForNetworkChanges(&hMonitor, pm); |
813 | ExitOnFailure(hr, "Failed to re-wait for network changes"); | 828 | MonExitOnFailure(hr, "Failed to re-wait for network changes"); |
814 | 829 | ||
815 | // Propagate any network status update messages to all waiter threads | 830 | // Propagate any network status update messages to all waiter threads |
816 | for (DWORD i = 0; i < pm->cWaiterThreads; ++i) | 831 | for (DWORD i = 0; i < pm->cWaiterThreads; ++i) |
@@ -819,12 +834,12 @@ static DWORD WINAPI CoordinatorThread( | |||
819 | 834 | ||
820 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_NETWORK_STATUS_UPDATE, 0, 0)) | 835 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_NETWORK_STATUS_UPDATE, 0, 0)) |
821 | { | 836 | { |
822 | ExitWithLastError(hr, "Failed to send message to waiter thread to notify of network status update"); | 837 | MonExitWithLastError(hr, "Failed to send message to waiter thread to notify of network status update"); |
823 | } | 838 | } |
824 | 839 | ||
825 | if (!::SetEvent(pWaiterContext->rgHandles[0])) | 840 | if (!::SetEvent(pWaiterContext->rgHandles[0])) |
826 | { | 841 | { |
827 | ExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming network status update message"); | 842 | MonExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming network status update message"); |
828 | } | 843 | } |
829 | } | 844 | } |
830 | break; | 845 | break; |
@@ -837,12 +852,12 @@ static DWORD WINAPI CoordinatorThread( | |||
837 | 852 | ||
838 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, msg.wParam == uTimerFailedNetworkRetry ? MON_MESSAGE_NETWORK_RETRY_FAILED_NETWORK_WAITS : MON_MESSAGE_NETWORK_RETRY_SUCCESSFUL_NETWORK_WAITS, 0, 0)) | 853 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, msg.wParam == uTimerFailedNetworkRetry ? MON_MESSAGE_NETWORK_RETRY_FAILED_NETWORK_WAITS : MON_MESSAGE_NETWORK_RETRY_SUCCESSFUL_NETWORK_WAITS, 0, 0)) |
839 | { | 854 | { |
840 | ExitWithLastError(hr, "Failed to send message to waiter thread to notify of network status update"); | 855 | MonExitWithLastError(hr, "Failed to send message to waiter thread to notify of network status update"); |
841 | } | 856 | } |
842 | 857 | ||
843 | if (!::SetEvent(pWaiterContext->rgHandles[0])) | 858 | if (!::SetEvent(pWaiterContext->rgHandles[0])) |
844 | { | 859 | { |
845 | ExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming network status update message"); | 860 | MonExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming network status update message"); |
846 | } | 861 | } |
847 | } | 862 | } |
848 | break; | 863 | break; |
@@ -861,12 +876,12 @@ static DWORD WINAPI CoordinatorThread( | |||
861 | 876 | ||
862 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_DRIVE_STATUS_UPDATE, msg.wParam, msg.lParam)) | 877 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_DRIVE_STATUS_UPDATE, msg.wParam, msg.lParam)) |
863 | { | 878 | { |
864 | ExitWithLastError(hr, "Failed to send message to waiter thread to notify of drive status update"); | 879 | MonExitWithLastError(hr, "Failed to send message to waiter thread to notify of drive status update"); |
865 | } | 880 | } |
866 | 881 | ||
867 | if (!::SetEvent(pWaiterContext->rgHandles[0])) | 882 | if (!::SetEvent(pWaiterContext->rgHandles[0])) |
868 | { | 883 | { |
869 | ExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming drive status update message"); | 884 | MonExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming drive status update message"); |
870 | } | 885 | } |
871 | } | 886 | } |
872 | break; | 887 | break; |
@@ -998,7 +1013,7 @@ static HRESULT InitiateWait( | |||
998 | { | 1013 | { |
999 | continue; | 1014 | continue; |
1000 | } | 1015 | } |
1001 | ExitOnWin32Error(er, hr, "Failed to wait on path %ls", pRequest->rgsczPathHierarchy[dwIndex]); | 1016 | MonExitOnWin32Error(er, hr, "Failed to wait on path %ls", pRequest->rgsczPathHierarchy[dwIndex]); |
1002 | } | 1017 | } |
1003 | else | 1018 | else |
1004 | { | 1019 | { |
@@ -1013,7 +1028,7 @@ static HRESULT InitiateWait( | |||
1013 | { | 1028 | { |
1014 | continue; | 1029 | continue; |
1015 | } | 1030 | } |
1016 | ExitOnFailure(hr, "Failed to open regkey %ls", pRequest->rgsczPathHierarchy[dwIndex]); | 1031 | MonExitOnFailure(hr, "Failed to open regkey %ls", pRequest->rgsczPathHierarchy[dwIndex]); |
1017 | 1032 | ||
1018 | er = ::RegNotifyChangeKeyValue(pRequest->regkey.hkSubKey, GetRecursiveFlag(pRequest, dwIndex), REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY, *pHandle, TRUE); | 1033 | er = ::RegNotifyChangeKeyValue(pRequest->regkey.hkSubKey, GetRecursiveFlag(pRequest, dwIndex), REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY, *pHandle, TRUE); |
1019 | ReleaseRegKey(hk); | 1034 | ReleaseRegKey(hk); |
@@ -1024,7 +1039,7 @@ static HRESULT InitiateWait( | |||
1024 | } | 1039 | } |
1025 | else | 1040 | else |
1026 | { | 1041 | { |
1027 | ExitOnWin32Error(er, hr, "Failed to wait on subkey %ls", pRequest->rgsczPathHierarchy[dwIndex]); | 1042 | MonExitOnWin32Error(er, hr, "Failed to wait on subkey %ls", pRequest->rgsczPathHierarchy[dwIndex]); |
1028 | 1043 | ||
1029 | fHandleFound = TRUE; | 1044 | fHandleFound = TRUE; |
1030 | } | 1045 | } |
@@ -1062,7 +1077,7 @@ static HRESULT InitiateWait( | |||
1062 | } | 1077 | } |
1063 | } while (fRedo); | 1078 | } while (fRedo); |
1064 | 1079 | ||
1065 | ExitOnFailure(hr, "Didn't get a successful wait after looping through all available options %ls", pRequest->rgsczPathHierarchy[pRequest->cPathHierarchy - 1]); | 1080 | MonExitOnFailure(hr, "Didn't get a successful wait after looping through all available options %ls", pRequest->rgsczPathHierarchy[pRequest->cPathHierarchy - 1]); |
1066 | 1081 | ||
1067 | if (MON_DIRECTORY == pRequest->type) | 1082 | if (MON_DIRECTORY == pRequest->type) |
1068 | { | 1083 | { |
@@ -1141,7 +1156,7 @@ static DWORD WINAPI WaiterThread( | |||
1141 | } | 1156 | } |
1142 | 1157 | ||
1143 | hr = MemInsertIntoArray(reinterpret_cast<void **>(&pWaiterContext->rgHandles), dwNewRequestIndex + 1, 1, pWaiterContext->cHandles, sizeof(HANDLE), MON_ARRAY_GROWTH); | 1158 | hr = MemInsertIntoArray(reinterpret_cast<void **>(&pWaiterContext->rgHandles), dwNewRequestIndex + 1, 1, pWaiterContext->cHandles, sizeof(HANDLE), MON_ARRAY_GROWTH); |
1144 | ExitOnFailure(hr, "Failed to insert additional handle"); | 1159 | MonExitOnFailure(hr, "Failed to insert additional handle"); |
1145 | ++pWaiterContext->cHandles; | 1160 | ++pWaiterContext->cHandles; |
1146 | 1161 | ||
1147 | // Ugh - directory types start with INVALID_HANDLE_VALUE instead of NULL | 1162 | // Ugh - directory types start with INVALID_HANDLE_VALUE instead of NULL |
@@ -1151,7 +1166,7 @@ static DWORD WINAPI WaiterThread( | |||
1151 | } | 1166 | } |
1152 | 1167 | ||
1153 | hr = MemInsertIntoArray(reinterpret_cast<void **>(&pWaiterContext->rgRequests), dwNewRequestIndex, 1, pWaiterContext->cRequests, sizeof(MON_REQUEST), MON_ARRAY_GROWTH); | 1168 | hr = MemInsertIntoArray(reinterpret_cast<void **>(&pWaiterContext->rgRequests), dwNewRequestIndex, 1, pWaiterContext->cRequests, sizeof(MON_REQUEST), MON_ARRAY_GROWTH); |
1154 | ExitOnFailure(hr, "Failed to insert additional request struct"); | 1169 | MonExitOnFailure(hr, "Failed to insert additional request struct"); |
1155 | ++pWaiterContext->cRequests; | 1170 | ++pWaiterContext->cRequests; |
1156 | 1171 | ||
1157 | pWaiterContext->rgRequests[dwNewRequestIndex] = pAddMessage->request; | 1172 | pWaiterContext->rgRequests[dwNewRequestIndex] = pAddMessage->request; |
@@ -1172,10 +1187,10 @@ static DWORD WINAPI WaiterThread( | |||
1172 | } | 1187 | } |
1173 | else | 1188 | else |
1174 | { | 1189 | { |
1175 | ExitOnFailure(hr, "Failed to find request index for remove message"); | 1190 | MonExitOnFailure(hr, "Failed to find request index for remove message"); |
1176 | 1191 | ||
1177 | hr = RemoveRequest(pWaiterContext, dwRequestIndex); | 1192 | hr = RemoveRequest(pWaiterContext, dwRequestIndex); |
1178 | ExitOnFailure(hr, "Failed to remove request after request from coordinator thread."); | 1193 | MonExitOnFailure(hr, "Failed to remove request after request from coordinator thread."); |
1179 | } | 1194 | } |
1180 | 1195 | ||
1181 | MonRemoveMessageDestroy(pRemoveMessage); | 1196 | MonRemoveMessageDestroy(pRemoveMessage); |
@@ -1204,7 +1219,7 @@ static DWORD WINAPI WaiterThread( | |||
1204 | hrTemp = InitiateWait(pWaiterContext->rgRequests + i, pWaiterContext->rgHandles + i + 1); | 1219 | hrTemp = InitiateWait(pWaiterContext->rgRequests + i, pWaiterContext->rgHandles + i + 1); |
1205 | 1220 | ||
1206 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); | 1221 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); |
1207 | ExitOnFailure(hr, "Failed to update wait status"); | 1222 | MonExitOnFailure(hr, "Failed to update wait status"); |
1208 | hrTemp = S_OK; | 1223 | hrTemp = S_OK; |
1209 | 1224 | ||
1210 | if (dwNewRequestIndex != i) | 1225 | if (dwNewRequestIndex != i) |
@@ -1239,7 +1254,7 @@ static DWORD WINAPI WaiterThread( | |||
1239 | hrTemp = InitiateWait(pWaiterContext->rgRequests + i, pWaiterContext->rgHandles + i + 1); | 1254 | hrTemp = InitiateWait(pWaiterContext->rgRequests + i, pWaiterContext->rgHandles + i + 1); |
1240 | 1255 | ||
1241 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); | 1256 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); |
1242 | ExitOnFailure(hr, "Failed to update wait status"); | 1257 | MonExitOnFailure(hr, "Failed to update wait status"); |
1243 | hrTemp = S_OK; | 1258 | hrTemp = S_OK; |
1244 | 1259 | ||
1245 | if (dwNewRequestIndex != i) | 1260 | if (dwNewRequestIndex != i) |
@@ -1274,7 +1289,7 @@ static DWORD WINAPI WaiterThread( | |||
1274 | hrTemp = InitiateWait(pWaiterContext->rgRequests + i, pWaiterContext->rgHandles + i + 1); | 1289 | hrTemp = InitiateWait(pWaiterContext->rgRequests + i, pWaiterContext->rgHandles + i + 1); |
1275 | 1290 | ||
1276 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); | 1291 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); |
1277 | ExitOnFailure(hr, "Failed to update wait status"); | 1292 | MonExitOnFailure(hr, "Failed to update wait status"); |
1278 | hrTemp = S_OK; | 1293 | hrTemp = S_OK; |
1279 | 1294 | ||
1280 | if (dwNewRequestIndex != i) | 1295 | if (dwNewRequestIndex != i) |
@@ -1311,7 +1326,7 @@ static DWORD WINAPI WaiterThread( | |||
1311 | } | 1326 | } |
1312 | 1327 | ||
1313 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); | 1328 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); |
1314 | ExitOnFailure(hr, "Failed to update wait status"); | 1329 | MonExitOnFailure(hr, "Failed to update wait status"); |
1315 | hrTemp = S_OK; | 1330 | hrTemp = S_OK; |
1316 | 1331 | ||
1317 | if (dwNewRequestIndex != i) | 1332 | if (dwNewRequestIndex != i) |
@@ -1354,7 +1369,7 @@ static DWORD WINAPI WaiterThread( | |||
1354 | hrTemp = E_PATHNOTFOUND; | 1369 | hrTemp = E_PATHNOTFOUND; |
1355 | 1370 | ||
1356 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); | 1371 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, i, &dwNewRequestIndex); |
1357 | ExitOnFailure(hr, "Failed to update wait status"); | 1372 | MonExitOnFailure(hr, "Failed to update wait status"); |
1358 | hrTemp = S_OK; | 1373 | hrTemp = S_OK; |
1359 | break; | 1374 | break; |
1360 | } | 1375 | } |
@@ -1385,7 +1400,7 @@ static DWORD WINAPI WaiterThread( | |||
1385 | // Initiate re-waits before we notify callback, to ensure we don't miss a single update | 1400 | // Initiate re-waits before we notify callback, to ensure we don't miss a single update |
1386 | hrTemp = InitiateWait(pWaiterContext->rgRequests + dwRequestIndex, pWaiterContext->rgHandles + dwRequestIndex + 1); | 1401 | hrTemp = InitiateWait(pWaiterContext->rgRequests + dwRequestIndex, pWaiterContext->rgHandles + dwRequestIndex + 1); |
1387 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, dwRequestIndex, &dwRequestIndex); | 1402 | hr = UpdateWaitStatus(hrTemp, pWaiterContext, dwRequestIndex, &dwRequestIndex); |
1388 | ExitOnFailure(hr, "Failed to update wait status"); | 1403 | MonExitOnFailure(hr, "Failed to update wait status"); |
1389 | hrTemp = S_OK; | 1404 | hrTemp = S_OK; |
1390 | 1405 | ||
1391 | // If there were no errors and we were already waiting on the right target, or if we weren't yet but are able to now, it's a successful notify | 1406 | // If there were no errors and we were already waiting on the right target, or if we weren't yet but are able to now, it's a successful notify |
@@ -1413,7 +1428,7 @@ static DWORD WINAPI WaiterThread( | |||
1413 | } | 1428 | } |
1414 | else if (WAIT_TIMEOUT != dwRet) | 1429 | else if (WAIT_TIMEOUT != dwRet) |
1415 | { | 1430 | { |
1416 | ExitWithLastError(hr, "Failed to wait for multiple objects with return code %u", dwRet); | 1431 | MonExitWithLastError(hr, "Failed to wait for multiple objects with return code %u", dwRet); |
1417 | } | 1432 | } |
1418 | 1433 | ||
1419 | // OK, now that we've checked all triggered handles (resetting silence period timers appropriately), check for any pending notifications that we can finally fire | 1434 | // OK, now that we've checked all triggered handles (resetting silence period timers appropriately), check for any pending notifications that we can finally fire |
@@ -1432,7 +1447,7 @@ static DWORD WINAPI WaiterThread( | |||
1432 | { | 1447 | { |
1433 | Assert(FALSE); | 1448 | Assert(FALSE); |
1434 | hr = HRESULT_FROM_WIN32(ERROR_EA_LIST_INCONSISTENT); | 1449 | hr = HRESULT_FROM_WIN32(ERROR_EA_LIST_INCONSISTENT); |
1435 | ExitOnFailure(hr, "Phantom pending fires were found!"); | 1450 | MonExitOnFailure(hr, "Phantom pending fires were found!"); |
1436 | } | 1451 | } |
1437 | --cRequestsPendingBeforeLoop; | 1452 | --cRequestsPendingBeforeLoop; |
1438 | 1453 | ||
@@ -1470,13 +1485,13 @@ static DWORD WINAPI WaiterThread( | |||
1470 | { | 1485 | { |
1471 | Assert(FALSE); | 1486 | Assert(FALSE); |
1472 | hr = HRESULT_FROM_WIN32(PEERDIST_ERROR_MISSING_DATA); | 1487 | hr = HRESULT_FROM_WIN32(PEERDIST_ERROR_MISSING_DATA); |
1473 | ExitOnFailure(hr, "Missing %u pending fires! Total pending fires: %u, wait: %u", cRequestsPendingBeforeLoop, pWaiterContext->cRequestsPending, dwWait); | 1488 | MonExitOnFailure(hr, "Missing %u pending fires! Total pending fires: %u, wait: %u", cRequestsPendingBeforeLoop, pWaiterContext->cRequestsPending, dwWait); |
1474 | } | 1489 | } |
1475 | if (0 < pWaiterContext->cRequestsPending && DWORD_MAX == dwWait) | 1490 | if (0 < pWaiterContext->cRequestsPending && DWORD_MAX == dwWait) |
1476 | { | 1491 | { |
1477 | Assert(FALSE); | 1492 | Assert(FALSE); |
1478 | hr = HRESULT_FROM_WIN32(ERROR_CANT_WAIT); | 1493 | hr = HRESULT_FROM_WIN32(ERROR_CANT_WAIT); |
1479 | ExitOnFailure(hr, "Pending fires exist, but wait was infinite", cRequestsPendingBeforeLoop); | 1494 | MonExitOnFailure(hr, "Pending fires exist (%u), but wait was infinite", cRequestsPendingBeforeLoop); |
1480 | } | 1495 | } |
1481 | } | 1496 | } |
1482 | } while (fContinue); | 1497 | } while (fContinue); |
@@ -1651,7 +1666,7 @@ static HRESULT RemoveRequest( | |||
1651 | // Notify coordinator thread that a wait was removed | 1666 | // Notify coordinator thread that a wait was removed |
1652 | if (!::PostThreadMessageW(pWaiterContext->dwCoordinatorThreadId, MON_MESSAGE_REMOVED, static_cast<WPARAM>(::GetCurrentThreadId()), 0)) | 1667 | if (!::PostThreadMessageW(pWaiterContext->dwCoordinatorThreadId, MON_MESSAGE_REMOVED, static_cast<WPARAM>(::GetCurrentThreadId()), 0)) |
1653 | { | 1668 | { |
1654 | ExitWithLastError(hr, "Failed to send message to coordinator thread to confirm directory was removed."); | 1669 | MonExitWithLastError(hr, "Failed to send message to coordinator thread to confirm directory was removed."); |
1655 | } | 1670 | } |
1656 | 1671 | ||
1657 | LExit: | 1672 | LExit: |
@@ -1684,7 +1699,7 @@ static HRESULT DuplicateRemoveMessage( | |||
1684 | HRESULT hr = S_OK; | 1699 | HRESULT hr = S_OK; |
1685 | 1700 | ||
1686 | *ppMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(MemAlloc(sizeof(MON_REMOVE_MESSAGE), TRUE)); | 1701 | *ppMessage = reinterpret_cast<MON_REMOVE_MESSAGE *>(MemAlloc(sizeof(MON_REMOVE_MESSAGE), TRUE)); |
1687 | ExitOnNull(*ppMessage, hr, E_OUTOFMEMORY, "Failed to allocate copy of remove message"); | 1702 | MonExitOnNull(*ppMessage, hr, E_OUTOFMEMORY, "Failed to allocate copy of remove message"); |
1688 | 1703 | ||
1689 | (*ppMessage)->type = pMessage->type; | 1704 | (*ppMessage)->type = pMessage->type; |
1690 | (*ppMessage)->fRecursive = pMessage->fRecursive; | 1705 | (*ppMessage)->fRecursive = pMessage->fRecursive; |
@@ -1693,13 +1708,13 @@ static HRESULT DuplicateRemoveMessage( | |||
1693 | { | 1708 | { |
1694 | case MON_DIRECTORY: | 1709 | case MON_DIRECTORY: |
1695 | hr = StrAllocString(&(*ppMessage)->directory.sczDirectory, pMessage->directory.sczDirectory, 0); | 1710 | hr = StrAllocString(&(*ppMessage)->directory.sczDirectory, pMessage->directory.sczDirectory, 0); |
1696 | ExitOnFailure(hr, "Failed to copy directory"); | 1711 | MonExitOnFailure(hr, "Failed to copy directory"); |
1697 | break; | 1712 | break; |
1698 | case MON_REGKEY: | 1713 | case MON_REGKEY: |
1699 | (*ppMessage)->regkey.hkRoot = pMessage->regkey.hkRoot; | 1714 | (*ppMessage)->regkey.hkRoot = pMessage->regkey.hkRoot; |
1700 | (*ppMessage)->regkey.kbKeyBitness = pMessage->regkey.kbKeyBitness; | 1715 | (*ppMessage)->regkey.kbKeyBitness = pMessage->regkey.kbKeyBitness; |
1701 | hr = StrAllocString(&(*ppMessage)->regkey.sczSubKey, pMessage->regkey.sczSubKey, 0); | 1716 | hr = StrAllocString(&(*ppMessage)->regkey.sczSubKey, pMessage->regkey.sczSubKey, 0); |
1702 | ExitOnFailure(hr, "Failed to copy subkey"); | 1717 | MonExitOnFailure(hr, "Failed to copy subkey"); |
1703 | break; | 1718 | break; |
1704 | default: | 1719 | default: |
1705 | Assert(false); | 1720 | Assert(false); |
@@ -1764,7 +1779,7 @@ static LRESULT CALLBACK MonWndProc( | |||
1764 | // This drive had a status update, so send it out to all threads | 1779 | // This drive had a status update, so send it out to all threads |
1765 | if (!::PostThreadMessageW(::GetCurrentThreadId(), MON_MESSAGE_DRIVE_STATUS_UPDATE, static_cast<WPARAM>(chDrive), static_cast<LPARAM>(fArrival))) | 1780 | if (!::PostThreadMessageW(::GetCurrentThreadId(), MON_MESSAGE_DRIVE_STATUS_UPDATE, static_cast<WPARAM>(chDrive), static_cast<LPARAM>(fArrival))) |
1766 | { | 1781 | { |
1767 | ExitWithLastError(hr, "Failed to send drive status update with drive %wc and arrival %ls", chDrive, fArrival ? L"TRUE" : L"FALSE"); | 1782 | MonExitWithLastError(hr, "Failed to send drive status update with drive %wc and arrival %ls", chDrive, fArrival ? L"TRUE" : L"FALSE"); |
1768 | } | 1783 | } |
1769 | } | 1784 | } |
1770 | dwUnitMask >>= 1; | 1785 | dwUnitMask >>= 1; |
@@ -1773,7 +1788,7 @@ static LRESULT CALLBACK MonWndProc( | |||
1773 | if (chDrive == 'z') | 1788 | if (chDrive == 'z') |
1774 | { | 1789 | { |
1775 | hr = E_UNEXPECTED; | 1790 | hr = E_UNEXPECTED; |
1776 | ExitOnFailure(hr, "UnitMask showed drives beyond z:. Remaining UnitMask at this point: %u", dwUnitMask); | 1791 | MonExitOnFailure(hr, "UnitMask showed drives beyond z:. Remaining UnitMask at this point: %u", dwUnitMask); |
1777 | } | 1792 | } |
1778 | } | 1793 | } |
1779 | } | 1794 | } |
@@ -1785,7 +1800,7 @@ static LRESULT CALLBACK MonWndProc( | |||
1785 | if (!pm) | 1800 | if (!pm) |
1786 | { | 1801 | { |
1787 | hr = E_POINTER; | 1802 | hr = E_POINTER; |
1788 | ExitOnFailure(hr, "DBT_DEVICEQUERYREMOVE message received with no MON_STRUCT pointer, so message was ignored"); | 1803 | MonExitOnFailure(hr, "DBT_DEVICEQUERYREMOVE message received with no MON_STRUCT pointer, so message was ignored"); |
1789 | } | 1804 | } |
1790 | 1805 | ||
1791 | fReturnTrue = TRUE; | 1806 | fReturnTrue = TRUE; |
@@ -1796,7 +1811,7 @@ static LRESULT CALLBACK MonWndProc( | |||
1796 | // We must wait for the actual wait handle to be released by waiter thread before telling windows to proceed with device removal, otherwise it could fail | 1811 | // We must wait for the actual wait handle to be released by waiter thread before telling windows to proceed with device removal, otherwise it could fail |
1797 | // due to handles still being open, so use a MON_INTERNAL_TEMPORARY_WAIT struct to send and receive a reply from a waiter thread | 1812 | // due to handles still being open, so use a MON_INTERNAL_TEMPORARY_WAIT struct to send and receive a reply from a waiter thread |
1798 | pm->internalWait.hWait = ::CreateEventW(NULL, TRUE, FALSE, NULL); | 1813 | pm->internalWait.hWait = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
1799 | ExitOnNullWithLastError(pm->internalWait.hWait, hr, "Failed to create anonymous event for waiter to notify wndproc device can be removed"); | 1814 | MonExitOnNullWithLastError(pm->internalWait.hWait, hr, "Failed to create anonymous event for waiter to notify wndproc device can be removed"); |
1800 | 1815 | ||
1801 | pHandle = reinterpret_cast<DEV_BROADCAST_HANDLE*>(lParam); | 1816 | pHandle = reinterpret_cast<DEV_BROADCAST_HANDLE*>(lParam); |
1802 | pm->internalWait.pvContext = pHandle->dbch_handle; | 1817 | pm->internalWait.pvContext = pHandle->dbch_handle; |
@@ -1808,12 +1823,12 @@ static LRESULT CALLBACK MonWndProc( | |||
1808 | 1823 | ||
1809 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_DRIVE_QUERY_REMOVE, reinterpret_cast<WPARAM>(&pm->internalWait), static_cast<LPARAM>(pm->internalWait.dwSendIteration))) | 1824 | if (!::PostThreadMessageW(pWaiterContext->dwWaiterThreadId, MON_MESSAGE_DRIVE_QUERY_REMOVE, reinterpret_cast<WPARAM>(&pm->internalWait), static_cast<LPARAM>(pm->internalWait.dwSendIteration))) |
1810 | { | 1825 | { |
1811 | ExitWithLastError(hr, "Failed to send message to waiter thread to notify of drive query remove"); | 1826 | MonExitWithLastError(hr, "Failed to send message to waiter thread to notify of drive query remove"); |
1812 | } | 1827 | } |
1813 | 1828 | ||
1814 | if (!::SetEvent(pWaiterContext->rgHandles[0])) | 1829 | if (!::SetEvent(pWaiterContext->rgHandles[0])) |
1815 | { | 1830 | { |
1816 | ExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming drive query remove message"); | 1831 | MonExitWithLastError(hr, "Failed to set event to notify waiter thread of incoming drive query remove message"); |
1817 | } | 1832 | } |
1818 | } | 1833 | } |
1819 | 1834 | ||
@@ -1833,7 +1848,7 @@ static LRESULT CALLBACK MonWndProc( | |||
1833 | } | 1848 | } |
1834 | else | 1849 | else |
1835 | { | 1850 | { |
1836 | ExitWithLastError(hr, "WaitForSingleObject failed with non-timeout reason while waiting for response from waiter thread"); | 1851 | MonExitWithLastError(hr, "WaitForSingleObject failed with non-timeout reason while waiting for response from waiter thread"); |
1837 | } | 1852 | } |
1838 | ++pm->internalWait.dwSendIteration; | 1853 | ++pm->internalWait.dwSendIteration; |
1839 | } | 1854 | } |
@@ -1871,12 +1886,12 @@ static HRESULT CreateMonWindow( | |||
1871 | { | 1886 | { |
1872 | if (ERROR_CLASS_ALREADY_EXISTS != ::GetLastError()) | 1887 | if (ERROR_CLASS_ALREADY_EXISTS != ::GetLastError()) |
1873 | { | 1888 | { |
1874 | ExitWithLastError(hr, "Failed to register MonUtil window class."); | 1889 | MonExitWithLastError(hr, "Failed to register MonUtil window class."); |
1875 | } | 1890 | } |
1876 | } | 1891 | } |
1877 | 1892 | ||
1878 | *pHwnd = ::CreateWindowExW(0, wc.lpszClassName, L"", 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HWND_DESKTOP, NULL, wc.hInstance, pm); | 1893 | *pHwnd = ::CreateWindowExW(0, wc.lpszClassName, L"", 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HWND_DESKTOP, NULL, wc.hInstance, pm); |
1879 | ExitOnNullWithLastError(*pHwnd, hr, "Failed to create window."); | 1894 | MonExitOnNullWithLastError(*pHwnd, hr, "Failed to create window."); |
1880 | 1895 | ||
1881 | // Rumor has it that drive arrival / removal events can be lost in the rare event that some other application higher up in z-order is hanging if we don't make our window topmost | 1896 | // Rumor has it that drive arrival / removal events can be lost in the rare event that some other application higher up in z-order is hanging if we don't make our window topmost |
1882 | // SWP_NOACTIVATE is important so the currently active window doesn't lose focus | 1897 | // SWP_NOACTIVATE is important so the currently active window doesn't lose focus |
@@ -1909,7 +1924,7 @@ static HRESULT WaitForNetworkChanges( | |||
1909 | if (::WSALookupServiceBegin(&qsRestrictions, LUP_RETURN_ALL, phMonitor)) | 1924 | if (::WSALookupServiceBegin(&qsRestrictions, LUP_RETURN_ALL, phMonitor)) |
1910 | { | 1925 | { |
1911 | hr = HRESULT_FROM_WIN32(::WSAGetLastError()); | 1926 | hr = HRESULT_FROM_WIN32(::WSAGetLastError()); |
1912 | ExitOnFailure(hr, "WSALookupServiceBegin() failed"); | 1927 | MonExitOnFailure(hr, "WSALookupServiceBegin() failed"); |
1913 | } | 1928 | } |
1914 | 1929 | ||
1915 | wsaCompletion.Type = NSP_NOTIFY_HWND; | 1930 | wsaCompletion.Type = NSP_NOTIFY_HWND; |
@@ -1923,7 +1938,7 @@ static HRESULT WaitForNetworkChanges( | |||
1923 | { | 1938 | { |
1924 | hr = E_FAIL; | 1939 | hr = E_FAIL; |
1925 | } | 1940 | } |
1926 | ExitOnFailure(hr, "WSANSPIoctl() failed with return code %i, wsa last error %u", nResult, ::WSAGetLastError()); | 1941 | MonExitOnFailure(hr, "WSANSPIoctl() failed with return code %i, wsa last error %u", nResult, ::WSAGetLastError()); |
1927 | } | 1942 | } |
1928 | 1943 | ||
1929 | LExit: | 1944 | LExit: |
@@ -1960,7 +1975,7 @@ static HRESULT UpdateWaitStatus( | |||
1960 | // If it's a network wait, notify coordinator thread that a network wait is failing | 1975 | // If it's a network wait, notify coordinator thread that a network wait is failing |
1961 | if (pRequest->fNetwork && !::PostThreadMessageW(pWaiterContext->dwCoordinatorThreadId, MON_MESSAGE_NETWORK_WAIT_FAILED, 0, 0)) | 1976 | if (pRequest->fNetwork && !::PostThreadMessageW(pWaiterContext->dwCoordinatorThreadId, MON_MESSAGE_NETWORK_WAIT_FAILED, 0, 0)) |
1962 | { | 1977 | { |
1963 | ExitWithLastError(hr, "Failed to send message to coordinator thread to notify a network wait started to fail"); | 1978 | MonExitWithLastError(hr, "Failed to send message to coordinator thread to notify a network wait started to fail"); |
1964 | } | 1979 | } |
1965 | 1980 | ||
1966 | // Move the failing wait to the end of the list of waits and increment cRequestsFailing so WaitForMultipleObjects isn't passed an invalid handle | 1981 | // Move the failing wait to the end of the list of waits and increment cRequestsFailing so WaitForMultipleObjects isn't passed an invalid handle |
@@ -1981,7 +1996,7 @@ static HRESULT UpdateWaitStatus( | |||
1981 | // If it's a network wait, notify coordinator thread that a network wait is succeeding again | 1996 | // If it's a network wait, notify coordinator thread that a network wait is succeeding again |
1982 | if (pRequest->fNetwork && !::PostThreadMessageW(pWaiterContext->dwCoordinatorThreadId, MON_MESSAGE_NETWORK_WAIT_SUCCEEDED, 0, 0)) | 1997 | if (pRequest->fNetwork && !::PostThreadMessageW(pWaiterContext->dwCoordinatorThreadId, MON_MESSAGE_NETWORK_WAIT_SUCCEEDED, 0, 0)) |
1983 | { | 1998 | { |
1984 | ExitWithLastError(hr, "Failed to send message to coordinator thread to notify a network wait is succeeding again"); | 1999 | MonExitWithLastError(hr, "Failed to send message to coordinator thread to notify a network wait is succeeding again"); |
1985 | } | 2000 | } |
1986 | 2001 | ||
1987 | --pWaiterContext->cRequestsFailing; | 2002 | --pWaiterContext->cRequestsFailing; |