[ros-diffs] [pschweitzer] 75348: [SHELL32] Avoid double-free and use-after-free in case the FSD fails to register the change directory notification CORE-13549
Author: pschweitzer Date: Sat Jul 15 07:45:28 2017 New Revision: 75348 URL: http://svn.reactos.org/svn/reactos?rev=75348&view=rev Log: [SHELL32] Avoid double-free and use-after-free in case the FSD fails to register the change directory notification CORE-13549 Modified: trunk/reactos/dll/win32/shell32/wine/changenotify.c Modified: trunk/reactos/dll/win32/shell32/wine/changenotify.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/wine/changenotify.c?rev=75348&r1=75347&r2=75348&view=diff == --- trunk/reactos/dll/win32/shell32/wine/changenotify.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/wine/changenotify.c [iso-8859-1] Sat Jul 15 07:45:28 2017 @@ -723,6 +723,20 @@ } #endif +#ifdef __REACTOS__ +/* This is to avoid double-free and potential use after free + * In case it failed, _BeginRead() already deferenced item + * But if failure comes the FSD, the APC routine (us) will + * be called as well, which will cause a double-free on quit. + * Avoid this by deferencing only once in case of failure and thus, + * incrementing reference count here + */ +if (dwErrorCode != ERROR_SUCCESS) +{ +InterlockedIncrement(&item->pParent->wQueuedCount); +} +#endif + /* This likely means overflow, so force whole directory refresh. */ if (!dwNumberOfBytesTransfered) {
[ros-diffs] [pschweitzer] 75349: [SHELL32] In case a FSD doesn't support directory changes notifications, don't try to requeue a notification each time it returns 0 data. Just quit instead. CORE-13549
Author: pschweitzer Date: Sat Jul 15 07:48:47 2017 New Revision: 75349 URL: http://svn.reactos.org/svn/reactos?rev=75349&view=rev Log: [SHELL32] In case a FSD doesn't support directory changes notifications, don't try to requeue a notification each time it returns 0 data. Just quit instead. CORE-13549 Modified: trunk/reactos/dll/win32/shell32/wine/changenotify.c Modified: trunk/reactos/dll/win32/shell32/wine/changenotify.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/wine/changenotify.c?rev=75349&r1=75348&r2=75349&view=diff == --- trunk/reactos/dll/win32/shell32/wine/changenotify.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/wine/changenotify.c [iso-8859-1] Sat Jul 15 07:48:47 2017 @@ -735,6 +735,15 @@ { InterlockedIncrement(&item->pParent->wQueuedCount); } + +/* If the FSD doesn't support directory change notifications, there's no + * no need to retry and requeue notification + */ +if (dwErrorCode == ERROR_INVALID_FUNCTION) +{ +WARN("Directory watching not supported\n"); +goto quit; +} #endif /* This likely means overflow, so force whole directory refresh. */
[ros-diffs] [gadamopoulos] 75350: [SHELL32] - CDesktopFolder: Create the enumerators of the internal fs folders and add their items in its own list instead of calling CreateFolderEnumList which enumer
Author: gadamopoulos Date: Sat Jul 15 09:18:06 2017 New Revision: 75350 URL: http://svn.reactos.org/svn/reactos?rev=75350&view=rev Log: [SHELL32] - CDesktopFolder: Create the enumerators of the internal fs folders and add their items in its own list instead of calling CreateFolderEnumList which enumerates ... files. - Remove CEnumIDListBase::CreateFolderEnumList and move its code to CFileSysEnum::Initialize. Modified: trunk/reactos/dll/win32/shell32/CEnumIDListBase.cpp trunk/reactos/dll/win32/shell32/CEnumIDListBase.h trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp Modified: trunk/reactos/dll/win32/shell32/CEnumIDListBase.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CEnumIDListBase.cpp?rev=75350&r1=75349&r2=75350&view=diff == --- trunk/reactos/dll/win32/shell32/CEnumIDListBase.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/CEnumIDListBase.cpp [iso-8859-1] Sat Jul 15 09:18:06 2017 @@ -123,73 +123,6 @@ return FALSE; } - -/** - * CreateFolderEnumList() - */ -BOOL CEnumIDListBase::CreateFolderEnumList( -LPCWSTR lpszPath, -DWORD dwFlags) -{ -WIN32_FIND_DATAW stffile; -HANDLE hFile; -WCHAR szPath[MAX_PATH]; -BOOL succeeded = TRUE; -static const WCHAR stars[] = { '*','.','*',0 }; -static const WCHAR dot[] = { '.',0 }; -static const WCHAR dotdot[] = { '.','.',0 }; - -TRACE("(%p)->(path=%s flags=0x%08x)\n", this, debugstr_w(lpszPath), dwFlags); - -if(!lpszPath || !lpszPath[0]) return FALSE; - -wcscpy(szPath, lpszPath); -PathAddBackslashW(szPath); -wcscat(szPath,stars); - -hFile = FindFirstFileW(szPath,&stffile); -if ( hFile != INVALID_HANDLE_VALUE ) -{ -BOOL findFinished = FALSE; - -do -{ -if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - || (dwFlags & SHCONTF_INCLUDEHIDDEN) ) -{ -LPITEMIDLIST pidl = NULL; - -if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && - dwFlags & SHCONTF_FOLDERS && - strcmpW(stffile.cFileName, dot) && strcmpW(stffile.cFileName, dotdot)) -{ -pidl = _ILCreateFromFindDataW(&stffile); -succeeded = succeeded && AddToEnumList(pidl); -} -else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - && dwFlags & SHCONTF_NONFOLDERS) -{ -pidl = _ILCreateFromFindDataW(&stffile); -succeeded = succeeded && AddToEnumList(pidl); -} -} -if (succeeded) -{ -if (!FindNextFileW(hFile, &stffile)) -{ -if (GetLastError() == ERROR_NO_MORE_FILES) -findFinished = TRUE; -else -succeeded = FALSE; -} -} -} while (succeeded && !findFinished); -FindClose(hFile); -} - -return succeeded; -} - /** * IEnumIDList_fnNext */ Modified: trunk/reactos/dll/win32/shell32/CEnumIDListBase.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CEnumIDListBase.h?rev=75350&r1=75349&r2=75350&view=diff == --- trunk/reactos/dll/win32/shell32/CEnumIDListBase.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/CEnumIDListBase.h [iso-8859-1] Sat Jul 15 09:18:06 2017 @@ -37,7 +37,6 @@ BOOL AddToEnumList(LPITEMIDLIST pidl); BOOL DeleteList(); BOOL HasItemWithCLSID(LPITEMIDLIST pidl); - BOOL CreateFolderEnumList(LPCWSTR lpszPath, DWORD dwFlags); // *** IEnumIDList methods *** virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched); Modified: trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp?rev=75350&r1=75349&r2=75350&view=diff == --- trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] Sat Jul 15 09:18:06 2017 @@ -53,7 +53,7 @@ public: CDesktopFolderEnum(); ~CDesktopFolderEnum(); -HRESULT WINAPI Initialize(CDesktopFolder *desktopFolder, HWND hwndOwner, DWORD dwFlags); +HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList *pDesktopEnumerator, IEnumID
[ros-diffs] [mjansen] 75351: [USBPORT] Fix incorrect transfer direction for URBs. Patch by Vadim Galyant. CORE-13546
Author: mjansen Date: Sat Jul 15 09:24:30 2017 New Revision: 75351 URL: http://svn.reactos.org/svn/reactos?rev=75351&view=rev Log: [USBPORT] Fix incorrect transfer direction for URBs. Patch by Vadim Galyant. CORE-13546 Modified: trunk/reactos/drivers/usb/usbport/urb.c trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h Modified: trunk/reactos/drivers/usb/usbport/urb.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/urb.c?rev=75351&r1=75350&r2=75351&view=diff == --- trunk/reactos/drivers/usb/usbport/urb.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbport/urb.c [iso-8859-1] Sat Jul 15 09:24:30 2017 @@ -385,13 +385,13 @@ if (Endpoint->EndpointProperties.TransferType != USBPORT_TRANSFER_TYPE_CONTROL) { -if (Endpoint->EndpointProperties.Direction) +if (Endpoint->EndpointProperties.Direction == USBPORT_TRANSFER_DIRECTION_OUT) { -Urb->UrbBulkOrInterruptTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; +Urb->UrbBulkOrInterruptTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN; } else { -Urb->UrbBulkOrInterruptTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN; +Urb->UrbBulkOrInterruptTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; } } Modified: trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h?rev=75351&r1=75350&r2=75351&view=diff == --- trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h [iso-8859-1] (original) +++ trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h [iso-8859-1] Sat Jul 15 09:24:30 2017 @@ -580,6 +580,7 @@ C_ASSERT(sizeof(USBPORT_MINIPORT_INTERFACE) == 336); +#define USBPORT_TRANSFER_DIRECTION_OUT 1 // From host to device typedef struct _USBPORT_ENDPOINT_PROPERTIES { USHORT DeviceAddress; USHORT EndpointAddress;
[ros-diffs] [gadamopoulos] 75352: [SHELL32] -Move CFSExtractIcon_CreateInstance to CFSFolder.cpp
Author: gadamopoulos Date: Sat Jul 15 09:38:45 2017 New Revision: 75352 URL: http://svn.reactos.org/svn/reactos?rev=75352&view=rev Log: [SHELL32] -Move CFSExtractIcon_CreateInstance to CFSFolder.cpp Modified: trunk/reactos/dll/win32/shell32/folders.cpp trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp trunk/reactos/dll/win32/shell32/wine/shell32_main.h Modified: trunk/reactos/dll/win32/shell32/folders.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders.cpp?rev=75352&r1=75351&r2=75352&view=diff == --- trunk/reactos/dll/win32/shell32/folders.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders.cpp [iso-8859-1] Sat Jul 15 09:38:45 2017 @@ -25,69 +25,6 @@ DWORD NumIconOverlayHandlers = 0; IShellIconOverlayIdentifier ** Handlers = NULL; - -static HRESULT getIconLocationForFolder(IShellFolder * psf, LPCITEMIDLIST pidl, UINT uFlags, -LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags) -{ -static const WCHAR shellClassInfo[] = { '.', 'S', 'h', 'e', 'l', 'l', 'C', 'l', 'a', 's', 's', 'I', 'n', 'f', 'o', 0 }; -static const WCHAR iconFile[] = { 'I', 'c', 'o', 'n', 'F', 'i', 'l', 'e', 0 }; -static const WCHAR clsid[] = { 'C', 'L', 'S', 'I', 'D', 0 }; -static const WCHAR clsid2[] = { 'C', 'L', 'S', 'I', 'D', '2', 0 }; -static const WCHAR iconIndex[] = { 'I', 'c', 'o', 'n', 'I', 'n', 'd', 'e', 'x', 0 }; -static const WCHAR wszDesktopIni[] = { 'd','e','s','k','t','o','p','.','i','n','i',0 }; -int icon_idx; - -if (!(uFlags & GIL_DEFAULTICON) && (_ILGetFileAttributes(ILFindLastID(pidl), NULL, 0) & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0 ) -{ -WCHAR wszFolderPath[MAX_PATH]; - -if (!ILGetDisplayNameExW(psf, pidl, wszFolderPath, 0)) -return FALSE; - -PathAppendW(wszFolderPath, wszDesktopIni); - -if (PathFileExistsW(wszFolderPath)) -{ -WCHAR wszPath[MAX_PATH]; -WCHAR wszCLSIDValue[CHARS_IN_GUID]; - -if (GetPrivateProfileStringW(shellClassInfo, iconFile, NULL, wszPath, MAX_PATH, wszFolderPath)) -{ -ExpandEnvironmentStringsW(wszPath, szIconFile, cchMax); - -*piIndex = GetPrivateProfileIntW(shellClassInfo, iconIndex, 0, wszFolderPath); -return S_OK; -} -else if (GetPrivateProfileStringW(shellClassInfo, clsid, NULL, wszCLSIDValue, CHARS_IN_GUID, wszFolderPath) && -HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx)) -{ -*piIndex = icon_idx; -return S_OK; -} -else if (GetPrivateProfileStringW(shellClassInfo, clsid2, NULL, wszCLSIDValue, CHARS_IN_GUID, wszFolderPath) && -HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx)) -{ -*piIndex = icon_idx; -return S_OK; -} -} -} - -static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 }; - -if (!HCR_GetIconW(folder, szIconFile, NULL, cchMax, &icon_idx)) -{ -lstrcpynW(szIconFile, swShell32Name, cchMax); -icon_idx = -IDI_SHELL_FOLDER; -} - -if (uFlags & GIL_OPENICON) -*piIndex = icon_idx < 0 ? icon_idx - 1 : icon_idx + 1; -else -*piIndex = icon_idx; - -return S_OK; -} static void InitIconOverlays(void) { @@ -195,109 +132,3 @@ else return FALSE; } - -HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) -{ -CComPtr initIcon; -HRESULT hr; -int icon_idx = 0; -UINT flags = 0; // FIXME: Use it! -CHAR sTemp[MAX_PATH] = ""; -WCHAR wTemp[MAX_PATH] = L""; - -hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon)); -if (FAILED(hr)) -return hr; - -if (_ILIsFolder (pidl)) -{ -if (SUCCEEDED(getIconLocationForFolder(psf, - pidl, 0, wTemp, _countof(wTemp), - &icon_idx, - &flags))) -{ -initIcon->SetNormalIcon(wTemp, icon_idx); -// FIXME: if/when getIconLocationForFolder does something for -//GIL_FORSHORTCUT, code below should be uncommented. and -//the following line removed. -initIcon->SetShortcutIcon(wTemp, icon_idx); -} -if (SUCCEEDED(getIconLocationForFolder(psf, - pidl, GIL_DEFAULTICON, wTemp, _countof(wTemp), - &icon_idx, - &flags))) -{ -initIcon->SetDefaultIcon(wTemp, icon_idx); -} -// if (SUCCEEDED(getIconLocationForFolder(psf, -// pidl, GIL_FORSHORTC
[ros-diffs] [pschweitzer] 75353: [RDBSS] Implement RxNotifyChangeDirectory(), RxLowIoNotifyChangeDirectoryCompletion(), RxCancelNotifyChangeDirectoryRequestsForVNetRoot() This means the first parts of
Author: pschweitzer Date: Sat Jul 15 10:05:32 2017 New Revision: 75353 URL: http://svn.reactos.org/svn/reactos?rev=75353&view=rev Log: [RDBSS] Implement RxNotifyChangeDirectory(), RxLowIoNotifyChangeDirectoryCompletion(), RxCancelNotifyChangeDirectoryRequestsForVNetRoot() This means the first parts of the directory watch are here. Though, NFS driver doesn't support these, but at least, it reduces the UNIMPLEMENTED spam! CORE-11327 Modified: trunk/reactos/sdk/include/ddk/mrx.h trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c Modified: trunk/reactos/sdk/include/ddk/mrx.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/mrx.h?rev=75353&r1=75352&r2=75353&view=diff == --- trunk/reactos/sdk/include/ddk/mrx.h [iso-8859-1] (original) +++ trunk/reactos/sdk/include/ddk/mrx.h [iso-8859-1] Sat Jul 15 10:05:32 2017 @@ -1,5 +1,8 @@ #ifndef _RXMINIRDR_ #define _RXMINIRDR_ + +#define RxSetIoStatusStatus(R, S) (R)->CurrentIrp->IoStatus.Status = (S) +#define RxSetIoStatusInfo(R, I) (R)->CurrentIrp->IoStatus.Information = (I) #define RxShouldPostCompletion() ((KeGetCurrentIrql() >= DISPATCH_LEVEL)) Modified: trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c?rev=75353&r1=75352&r2=75353&view=diff == --- trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] Sat Jul 15 10:05:32 2017 @@ -913,13 +913,100 @@ UNIMPLEMENTED; } +/* + * @implemented + */ NTSTATUS RxCancelNotifyChangeDirectoryRequestsForVNetRoot( PV_NET_ROOT VNetRoot, BOOLEAN ForceFilesClosed) { -UNIMPLEMENTED; -return STATUS_NOT_IMPLEMENTED; +KIRQL OldIrql; +NTSTATUS Status; +PLIST_ENTRY Entry; +PRX_CONTEXT Context; +LIST_ENTRY ContextsToCancel; + +/* Init a list for the contexts to cancel */ +InitializeListHead(&ContextsToCancel); + +/* Lock our list lock */ +KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql); + +/* Now, browse all the active contexts, to find the associated ones */ +Entry = RxActiveContexts.Flink; +while (Entry != &RxActiveContexts) +{ +Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry); +Entry = Entry->Flink; + +/* Not the IRP we're looking for, ignore */ +if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL || +Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY) +{ +continue; +} + +/* Not the VNetRoot we're looking for, ignore */ +if (Context->pFcb == NULL || +(PV_NET_ROOT)Context->NotifyChangeDirectory.pVNetRoot != VNetRoot) +{ +continue; +} + +/* No cancel routine (can't be cancel, then), ignore */ +if (Context->MRxCancelRoutine == NULL) +{ +continue; +} + +/* At that point, we found a matching context + * If we're not asked to force close, then fail - it's still open + */ +if (!ForceFilesClosed) +{ +Status = STATUS_FILES_OPEN; +break; +} + +/* Mark our context as cancelled */ +SetFlag(Context->Flags, RX_CONTEXT_FLAG_CANCELLED); + +/* Move it to our list */ +RemoveEntryList(&Context->ContextListEntry); +InsertTailList(&ContextsToCancel, &Context->ContextListEntry); + +InterlockedIncrement((volatile long *)&Context->ReferenceCount); +} + +/* Done with the contexts */ +KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql); + +if (Status != STATUS_SUCCESS) +{ +return Status; +} + +/* Now, handle all our "extracted" contexts */ +while (!IsListEmpty(&ContextsToCancel)) +{ +Entry = RemoveHeadList(&ContextsToCancel); +Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry); + +/* If they had an associated IRP (should be always true) */ +if (Context->CurrentIrp != NULL) +{ +/* Then, call cancel routine */ +ASSERT(Context->MRxCancelRoutine != NULL); +DPRINT1("Canceling %p with %p\n", Context, Context->MRxCancelRoutine); +Context->MRxCancelRoutine(Context); +} + +/* And delete the context */ +RxDereferenceAndDeleteRxContext(Context); +} + +return Status; } VOID @@ -5329,6 +5416,25 @@ * @implemented */ NTSTATUS +NTAPI +RxLowIoNotifyChangeDirectoryCompletion( +PRX_CONTEXT RxContext) +{ +PAGED_CODE(); + +DPRINT("Completing NCD with: %lx, %lx\n", RxContext->IoStatusBlock.Status, RxContext->IoStatusBlock.Information); + +/* Just copy back the IO_STATUS to the IRP */ +RxSetIoStatusStatus(RxContext, RxContext->IoStatusBl
[ros-diffs] [pschweitzer] 75354: [RDBSS] Complementary to r75353: implement RxCancelNotifyChangeDirectoryRequestsForFobx() CORE-11327
Author: pschweitzer Date: Sat Jul 15 11:41:24 2017 New Revision: 75354 URL: http://svn.reactos.org/svn/reactos?rev=75354&view=rev Log: [RDBSS] Complementary to r75353: implement RxCancelNotifyChangeDirectoryRequestsForFobx() CORE-11327 Modified: trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c Modified: trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c?rev=75354&r1=75353&r2=75354&view=diff == --- trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] Sat Jul 15 11:41:24 2017 @@ -906,11 +906,81 @@ return STATUS_SUCCESS; } +/* + * @implemented + */ VOID RxCancelNotifyChangeDirectoryRequestsForFobx( PFOBX Fobx) { -UNIMPLEMENTED; +KIRQL OldIrql; +PLIST_ENTRY Entry; +PRX_CONTEXT Context; +LIST_ENTRY ContextsToCancel; + +/* Init a list for the contexts to cancel */ +InitializeListHead(&ContextsToCancel); + +/* Lock our list lock */ +KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql); + +/* Now, browse all the active contexts, to find the associated ones */ +Entry = RxActiveContexts.Flink; +while (Entry != &RxActiveContexts) +{ +Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry); +Entry = Entry->Flink; + +/* Not the IRP we're looking for, ignore */ +if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL || +Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY) +{ +continue; +} + +/* Not the FOBX we're looking for, ignore */ +if ((PFOBX)Context->pFobx != Fobx) +{ +continue; +} + +/* No cancel routine (can't be cancel, then), ignore */ +if (Context->MRxCancelRoutine == NULL) +{ +continue; +} + +/* Mark our context as cancelled */ +SetFlag(Context->Flags, RX_CONTEXT_FLAG_CANCELLED); + +/* Move it to our list */ +RemoveEntryList(&Context->ContextListEntry); +InsertTailList(&ContextsToCancel, &Context->ContextListEntry); + +InterlockedIncrement((volatile long *)&Context->ReferenceCount); +} + +/* Done with the contexts */ +KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql); + +/* Now, handle all our "extracted" contexts */ +while (!IsListEmpty(&ContextsToCancel)) +{ +Entry = RemoveHeadList(&ContextsToCancel); +Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry); + +/* If they had an associated IRP (should be always true) */ +if (Context->CurrentIrp != NULL) +{ +/* Then, call cancel routine */ +ASSERT(Context->MRxCancelRoutine != NULL); +DPRINT1("Canceling %p with %p\n", Context, Context->MRxCancelRoutine); +Context->MRxCancelRoutine(Context); +} + +/* And delete the context */ +RxDereferenceAndDeleteRxContext(Context); +} } /*