aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/monutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dutil/monutil.cpp205
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
5const int MON_THREAD_GROWTH = 5; 20const int MON_THREAD_GROWTH = 5;
6const int MON_ARRAY_GROWTH = 40; 21const int MON_ARRAY_GROWTH = 40;
7const int MON_MAX_MONITORS_PER_THREAD = 63; 22const 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 );
220static void MonAddMessageDestroy( 235static void MonAddMessageDestroy(
221 __in MON_ADD_MESSAGE *pMessage 236 __in_opt MON_ADD_MESSAGE *pMessage
222 ); 237 );
223static void MonRemoveMessageDestroy( 238static void MonRemoveMessageDestroy(
224 __in MON_REMOVE_MESSAGE *pMessage 239 __in_opt MON_REMOVE_MESSAGE *pMessage
225 ); 240 );
226static BOOL GetRecursiveFlag( 241static 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
268extern "C" HRESULT DAPI MonCreate( 283extern "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
313LExit: 328LExit:
@@ -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
579static void MonAddMessageDestroy( 594static 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
599static void MonRemoveMessageDestroy( 614static 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
1657LExit: 1672LExit:
@@ -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
1929LExit: 1944LExit:
@@ -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;