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