diff --git a/dokan/dokan.c b/dokan/dokan.c index 3c3526026..b5a7eeaaf 100644 --- a/dokan/dokan.c +++ b/dokan/dokan.c @@ -271,7 +271,7 @@ DokanLoop( BOOL status; ULONG returnedLength; DWORD result = 0; - + DWORD lastError = 0; RtlZeroMemory(buffer, sizeof(buffer)); device = CreateFile( @@ -307,8 +307,15 @@ DokanLoop( ); if (!status) { - DbgPrint("Ioctl failed with code %d\n", GetLastError()); - result = (DWORD)-1; + lastError = GetLastError(); + DbgPrint("Ioctl failed for wait with code %d.\n", lastError); + if (lastError == ERROR_NO_SYSTEM_RESOURCES) { + DbgPrint("Processing will continue\n"); + status = TRUE; + Sleep(200); + continue; + } + DbgPrint("Thread will be terminated\n"); break; } @@ -376,7 +383,8 @@ DokanLoop( } CloseHandle(device); - _endthreadex(result); + _endthreadex(result); + return result; } @@ -620,6 +628,9 @@ DokanStart(PDOKAN_INSTANCE Instance) if (Instance->DokanOptions->Options & DOKAN_OPTION_REMOVABLE) { eventStart.Flags |= DOKAN_EVENT_REMOVABLE; } + + eventStart.IrpTimeout = Instance->DokanOptions->Timeout; + SendToDevice( DOKAN_GLOBAL_DEVICE_NAME, diff --git a/dokan/dokan.h b/dokan/dokan.h index f14655a5a..06cbd0a80 100644 --- a/dokan/dokan.h +++ b/dokan/dokan.h @@ -54,6 +54,7 @@ typedef struct _DOKAN_OPTIONS { ULONG Options; // combination of DOKAN_OPTIONS_* ULONG64 GlobalContext; // FileSystem can store anything here LPCWSTR MountPoint; // mount point "M:\" (drive letter) or "C:\mount\dokan" (path in NTFS) + ULONG Timeout; // IrpTimeout in milliseconds } DOKAN_OPTIONS, *PDOKAN_OPTIONS; typedef struct _DOKAN_FILE_INFO { diff --git a/dokan_mirror/mirror.c b/dokan_mirror/mirror.c index c993938f8..324a02502 100644 --- a/dokan_mirror/mirror.c +++ b/dokan_mirror/mirror.c @@ -1156,7 +1156,8 @@ wmain(ULONG argc, PWCHAR argv[]) " /d (enable debug output)\n" " /s (use stderr for output)\n" " /n (use network drive)\n" - " /m (use removable drive)\n"); + " /m (use removable drive)\n" + " /i (Timeout in Milliseconds ex. /i 30000)\n"); return -1; } @@ -1195,6 +1196,10 @@ wmain(ULONG argc, PWCHAR argv[]) case L'm': dokanOptions->Options |= DOKAN_OPTION_REMOVABLE; break; + case L'i': + command++; + dokanOptions->Timeout = (ULONG)_wtol(argv[command]); + break; default: fwprintf(stderr, L"unknown command: %s\n", argv[command]); return -1; diff --git a/sys/close.c b/sys/close.c index f770369e1..42a557ca6 100644 --- a/sys/close.c +++ b/sys/close.c @@ -85,7 +85,7 @@ Return Value: fcb = ccb->Fcb; ASSERT(fcb != NULL); - DDbgPrint(" Free CCB:%X\n", ccb); + DDbgPrint(" Free CCB:%p\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); @@ -107,7 +107,7 @@ Return Value: if (eventContext == NULL) { //status = STATUS_INSUFFICIENT_RESOURCES; DDbgPrint(" eventContext == NULL\n"); - DDbgPrint(" Free CCB:%X\n", ccb); + DDbgPrint(" Free CCB:%p\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); status = STATUS_SUCCESS; @@ -121,7 +121,7 @@ Return Value: eventContext->Operation.Close.FileNameLength = fcb->FileName.Length; RtlCopyMemory(eventContext->Operation.Close.FileName, fcb->FileName.Buffer, fcb->FileName.Length); - DDbgPrint(" Free CCB:%X\n", ccb); + DDbgPrint(" Free CCB:%p\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); diff --git a/sys/create.c b/sys/create.c index 0a866a888..e86483373 100644 --- a/sys/create.c +++ b/sys/create.c @@ -180,7 +180,7 @@ DokanFreeFCB( RemoveEntryList(&Fcb->NextFCB); - DDbgPrint(" Free FCB:%X\n", Fcb); + DDbgPrint(" Free FCB:%p\n", Fcb); ExFreePool(Fcb->FileName.Buffer); #if _WIN32_WINNT >= 0x0501 @@ -492,7 +492,7 @@ Return Value: fcb = DokanGetFCB(vcb, fileName, fileNameLength); if (fcb == NULL) { - DDbgPrint(" Was not able to get FCB for fileName %s\n", fileName); + DDbgPrint(" Was not able to get FCB for fileName %ls\n", fileName); status = STATUS_INSUFFICIENT_RESOURCES; __leave; } @@ -649,7 +649,7 @@ DokanCompleteCreate( } } } else { - DDbgPrint(" IRP_MJ_CREATE failed. Free CCB:%X\n", ccb); + DDbgPrint(" IRP_MJ_CREATE failed. Free CCB:%p\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); } diff --git a/sys/device.c b/sys/device.c index dc86cdf99..bdb35e557 100644 --- a/sys/device.c +++ b/sys/device.c @@ -383,7 +383,7 @@ DiskDeviceControl( Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + uniqueId->UniqueIdLength; status = STATUS_SUCCESS; - DDbgPrint(" UniqueName %ws\n", uniqueId->UniqueId); + DDbgPrint(" UniqueName %u\n", (unsigned int)uniqueId->UniqueId); break; } else { Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID); diff --git a/sys/directory.c b/sys/directory.c index 5846f3329..1f6061b25 100644 --- a/sys/directory.c +++ b/sys/directory.c @@ -245,7 +245,7 @@ DokanQueryDirectory( fcb->FileName.Buffer, fcb->FileName.Length); // if search pattern is specified, copy it to EventContext - if (ccb->SearchPatternLength) { + if (ccb->SearchPatternLength && ccb->SearchPattern) { PVOID searchBuffer; eventContext->Operation.Directory.SearchPatternLength = ccb->SearchPatternLength; diff --git a/sys/dokan.c b/sys/dokan.c index 4e3304201..a00454ed8 100644 --- a/sys/dokan.c +++ b/sys/dokan.c @@ -273,7 +273,6 @@ Return Value: return status; } - DDbgPrint("<== DriverEntry\n"); return( status ); @@ -568,7 +567,7 @@ PrintIdType( BOOLEAN DokanCheckCCB( __in PDokanDCB Dcb, - __in PDokanCCB Ccb) + __in_opt PDokanCCB Ccb) { ASSERT(Dcb != NULL); if (GetIdentifierType(Dcb) != DCB) { @@ -576,13 +575,13 @@ DokanCheckCCB( return FALSE; } - if (Ccb == NULL) { + if (Ccb == NULL || Ccb == 0) { PrintIdType(Dcb); DDbgPrint(" ccb is NULL\n"); return FALSE; } - if (Ccb->MountId != Dcb->MountId) { + if (Ccb->MountId != Dcb->MountId) { DDbgPrint(" MountId is different\n"); return FALSE; } diff --git a/sys/dokan.h b/sys/dokan.h index d458663b5..963f2879b 100644 --- a/sys/dokan.h +++ b/sys/dokan.h @@ -149,7 +149,6 @@ typedef struct _DOKAN_GLOBAL { // the list of waiting IRP for mount service IRP_LIST PendingService; IRP_LIST NotifyService; - } DOKAN_GLOBAL, *PDOKAN_GLOBAL; @@ -204,6 +203,8 @@ typedef struct _DokanDiskControlBlock { CACHE_MANAGER_CALLBACKS CacheManagerCallbacks; CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks; + + ULONG IrpTimeout; } DokanDCB, *PDokanDCB; @@ -365,7 +366,7 @@ AllocateEventContext( __in PDokanDCB Dcb, __in PIRP Irp, __in ULONG EventContextLength, - __in PDokanCCB Ccb); + __in_opt PDokanCCB Ccb); VOID DokanFreeEventContext( @@ -545,7 +546,7 @@ DokanStopCheckThreadInternal( BOOLEAN DokanCheckCCB( __in PDokanDCB Dcb, - __in PDokanCCB Ccb); + __in_opt PDokanCCB Ccb); VOID DokanInitIrpList( diff --git a/sys/event.c b/sys/event.c index 6391deff6..14d7ce113 100644 --- a/sys/event.c +++ b/sys/event.c @@ -108,11 +108,12 @@ RegisterPendingIrpMain( PIRP_ENTRY irpEntry; PIO_STACK_LOCATION irpSp; KIRQL oldIrql; - + PDokanVCB vcb = NULL; + DDbgPrint("==> DokanRegisterPendingIrpMain\n"); if (GetIdentifierType(DeviceObject->DeviceExtension) == VCB) { - PDokanVCB vcb = DeviceObject->DeviceExtension; + vcb = DeviceObject->DeviceExtension; if (CheckMount && !vcb->Dcb->Mounted) { DDbgPrint(" device is not mounted\n"); return STATUS_INSUFFICIENT_RESOURCES; @@ -140,7 +141,12 @@ RegisterPendingIrpMain( irpEntry->IrpList = IrpList; irpEntry->Flags = Flags; - DokanUpdateTimeout(&irpEntry->TickCount, DOKAN_IRP_PENDING_TIMEOUT); + // Update the irp timeout for the entry + if (vcb) { + DokanUpdateTimeout(&irpEntry->TickCount, vcb->Dcb->IrpTimeout); + } else { + DokanUpdateTimeout(&irpEntry->TickCount, DOKAN_IRP_PENDING_TIMEOUT); + } //DDbgPrint(" Lock IrpList.ListLock\n"); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); @@ -521,8 +527,22 @@ DokanEventStart( sizeof(driverInfo->DeviceName) / sizeof(WCHAR), &(dcb->SymbolicLinkName->Buffer[deviceNamePos])); + // Set the irp timeout in milliseconds + // If the IrpTimeout is 0, we assume that the value was not changed + dcb->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT; + if (eventStart.IrpTimeout > 0) { + if (eventStart.IrpTimeout > DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX) { + eventStart.IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX; + } + + if (eventStart.IrpTimeout < DOKAN_IRP_PENDING_TIMEOUT) { + eventStart.IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT; + } + dcb->IrpTimeout = eventStart.IrpTimeout; + } + DDbgPrint(" DeviceName:%ws\n", driverInfo->DeviceName); - DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT); + DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT); dcb->UseAltStream = 0; if (eventStart.Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) { diff --git a/sys/notification.c b/sys/notification.c index 8c3a4081e..ec7aa431f 100644 --- a/sys/notification.c +++ b/sys/notification.c @@ -64,7 +64,7 @@ SetCommonEventContext( __in PDokanDCB Dcb, __in PEVENT_CONTEXT EventContext, __in PIRP Irp, - __in PDokanCCB Ccb) + __in_opt PDokanCCB Ccb) { PIO_STACK_LOCATION irpSp; @@ -114,7 +114,7 @@ AllocateEventContext( __in PDokanDCB Dcb, __in PIRP Irp, __in ULONG EventContextLength, - __in PDokanCCB Ccb + __in_opt PDokanCCB Ccb ) { PEVENT_CONTEXT eventContext; @@ -515,7 +515,7 @@ DokanEventRelease( ccbNext = ccbEntry->Flink; ccb = CONTAINING_RECORD(ccbEntry, DokanCCB, NextCCB); - DDbgPrint(" NotifyCleanup ccb:%X, context:%X, filename:%wZ\n", + DDbgPrint(" NotifyCleanup ccb:%p, context:%X, filename:%wZ\n", ccb, (ULONG)ccb->UserContext, &fcb->FileName); FsRtlNotifyCleanup(vcb->NotifySync, &vcb->DirNotifyList, ccb); } diff --git a/sys/public.h b/sys/public.h index dc8cc1f0a..106055079 100644 --- a/sys/public.h +++ b/sys/public.h @@ -293,6 +293,7 @@ typedef struct _EVENT_START { ULONG DeviceType; ULONG Flags; WCHAR DriveLetter; + ULONG IrpTimeout; } EVENT_START, *PEVENT_START; typedef struct _DOKAN_RENAME_INFORMATION { diff --git a/sys/read.c b/sys/read.c index 5efa6254f..a1a1c9648 100644 --- a/sys/read.c +++ b/sys/read.c @@ -95,7 +95,7 @@ Return Value: DDbgPrint(" ProcessId %lu\n", IoGetRequestorProcessId(Irp)); DokanPrintFileName(fileObject); - DDbgPrint(" ByteCount:%d ByteOffset:%d\n", bufferLength, byteOffset); + DDbgPrint(" ByteCount:%lu ByteOffset:%I64d\n", bufferLength, byteOffset.QuadPart); if (bufferLength == 0) { status = STATUS_SUCCESS; diff --git a/sys/security.c b/sys/security.c index 13002c5ce..47f916c80 100644 --- a/sys/security.c +++ b/sys/security.c @@ -109,7 +109,7 @@ DokanDispatchQuerySecurity( if (Irp->MdlAddress == NULL) { status = DokanAllocateMdl(Irp, bufferLength); if (!NT_SUCCESS(status)) { - ExFreePool(eventContext); + DokanFreeEventContext(eventContext); __leave; } flags = DOKAN_MDL_ALLOCATED; diff --git a/sys/sys.vcxproj b/sys/sys.vcxproj index 6998b44fe..5b5852255 100644 --- a/sys/sys.vcxproj +++ b/sys/sys.vcxproj @@ -157,60 +157,84 @@ dokan $(SolutionDir)$(Platform)\$(ConfigurationName)\ $(Platform)\$(ConfigurationName)\ + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan $(SolutionDir)$(Platform)\$(ConfigurationName)\ $(Platform)\$(ConfigurationName)\ + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan $(SolutionDir)$(Platform)\$(ConfigurationName)\ $(Platform)\$(ConfigurationName)\ + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan $(SolutionDir)$(Platform)\$(ConfigurationName)\ $(Platform)\$(ConfigurationName)\ + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan $(SolutionDir)$(Platform)\$(ConfigurationName)\ $(Platform)\$(ConfigurationName)\ + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan $(SolutionDir)$(Platform)\$(ConfigurationName)\ $(Platform)\$(ConfigurationName)\ + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false DbgengKernelDebugger dokan + ..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\CodeAnalysis\DriverRecommendedRules.ruleset + false @@ -219,11 +243,13 @@ false + false false + false false @@ -233,6 +259,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -241,6 +268,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -249,6 +277,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -257,6 +286,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -265,6 +295,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -273,6 +304,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -281,6 +313,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -289,6 +322,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -297,6 +331,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib @@ -305,6 +340,7 @@ false + false wdmsec.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib