From a04b410e692c08a1143c901e8265751c89a70819 Mon Sep 17 00:00:00 2001 From: Liryna Date: Sun, 13 Feb 2022 14:20:46 -0500 Subject: [PATCH] Library - Add 16-128k IoBatch/EventResult pool for read and write Most read & write in the real world are made with 4-128k buffers. Adding pools for those sizes avoids the repetitive alloc and free cost. --- dokan/cleanup.c | 3 +- dokan/create.c | 3 +- dokan/directory.c | 3 +- dokan/dokan.c | 64 +++++++++--- dokan/dokan_pool.c | 240 ++++++++++++++++++++++++++++++++++++++++++++- dokan/dokan_pool.h | 18 ++++ dokan/dokani.h | 7 +- dokan/fileinfo.c | 3 +- dokan/flush.c | 3 +- dokan/lock.c | 3 +- dokan/read.c | 3 +- dokan/security.c | 6 +- dokan/setfile.c | 6 +- dokan/volume.c | 3 +- dokan/write.c | 20 ++-- 15 files changed, 351 insertions(+), 34 deletions(-) diff --git a/dokan/cleanup.c b/dokan/cleanup.c index 6f81caad..7e144405 100644 --- a/dokan/cleanup.c +++ b/dokan/cleanup.c @@ -25,7 +25,8 @@ with this program. If not, see . VOID DispatchCleanup(PDOKAN_IO_EVENT IoEvent) { CheckFileName(IoEvent->EventContext->Operation.Cleanup.FileName); - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); IoEvent->EventResult->Status = STATUS_SUCCESS; // return success at any case diff --git a/dokan/create.c b/dokan/create.c index a56c6bb4..13cf42e3 100644 --- a/dokan/create.c +++ b/dokan/create.c @@ -120,7 +120,8 @@ VOID DispatchCreate(PDOKAN_IO_EVENT IoEvent) { CheckFileName(fileName); - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); assert(IoEvent->DokanOpenInfo == NULL); diff --git a/dokan/directory.c b/dokan/directory.c index 0a38521c..25bc62ab 100644 --- a/dokan/directory.c +++ b/dokan/directory.c @@ -635,7 +635,8 @@ VOID DispatchDirectoryInformation(PDOKAN_IO_EVENT IoEvent) { CreateDispatchCommon(IoEvent, IoEvent->EventContext->Operation.Directory.BufferLength, - /*ClearBuffer=*/TRUE); + /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); IoEvent->EventResult->Operation.Directory.Index = IoEvent->EventContext->Operation.Directory.FileIndex; diff --git a/dokan/dokan.c b/dokan/dokan.c index 52e80841..7feabe3b 100644 --- a/dokan/dokan.c +++ b/dokan/dokan.c @@ -376,10 +376,23 @@ VOID HandleProcessIoFatalError(PDOKAN_INSTANCE DokanInstance, OnDeviceIoCtlFailed(DokanInstance, Result); } -VOID FreeIoEventResult(PEVENT_INFORMATION EventResult, BOOL PoolAllocated) { +VOID FreeIoEventResult(PEVENT_INFORMATION EventResult, ULONG EventResultSize, + BOOL PoolAllocated) { if (EventResult) { if (PoolAllocated) { - PushEventResult(EventResult); + if (EventResultSize <= DOKAN_EVENT_INFO_DEFAULT_SIZE) { + PushEventResult(EventResult); + } else if (EventResultSize <= DOKAN_EVENT_INFO_16K_SIZE) { + Push16KEventResult(EventResult); + } else if (EventResultSize <= DOKAN_EVENT_INFO_32K_SIZE) { + Push32KEventResult(EventResult); + } else if (EventResultSize <= DOKAN_EVENT_INFO_64K_SIZE) { + Push64KEventResult(EventResult); + } else if (EventResultSize <= DOKAN_EVENT_INFO_128K_SIZE) { + Push128KEventResult(EventResult); + } else { + assert(FALSE); + } } else { FreeEventResult(EventResult); } @@ -419,11 +432,13 @@ DWORD SendAndPullEventInformation(PDOKAN_IO_EVENT IoEvent, DWORD lastError = 0; PCHAR inputBuffer = NULL; DWORD eventInfoSize = 0; + ULONG eventResultSize = 0; PEVENT_INFORMATION eventInfo = NULL; BOOL eventInfoPollAllocated = FALSE; if (IoEvent && IoEvent->EventResult) { eventInfo = IoEvent->EventResult; + eventResultSize = IoEvent->EventResultSize; eventInfoPollAllocated = IoEvent->PoolAllocated; inputBuffer = (PCHAR)eventInfo; eventInfoSize = @@ -455,7 +470,7 @@ DWORD SendAndPullEventInformation(PDOKAN_IO_EVENT IoEvent, )) { lastError = GetLastError(); if (eventInfo) { - FreeIoEventResult(eventInfo, eventInfoPollAllocated); + FreeIoEventResult(eventInfo, eventResultSize, eventInfoPollAllocated); } if (!IoBatch->DokanInstance->FileSystemStopped) { DokanDbgPrintW( @@ -466,7 +481,7 @@ DWORD SendAndPullEventInformation(PDOKAN_IO_EVENT IoEvent, return lastError; } if (eventInfo) { - FreeIoEventResult(eventInfo, eventInfoPollAllocated); + FreeIoEventResult(eventInfo, eventResultSize, eventInfoPollAllocated); } return 0; } @@ -897,7 +912,7 @@ ULONG DispatchGetEventInformationLength(ULONG bufferSize) { FIELD_OFFSET(EVENT_INFORMATION, Buffer[0]) + bufferSize); } -VOID CreateDispatchCommon(PDOKAN_IO_EVENT IoEvent, ULONG SizeOfEventInfo, BOOL ClearBuffer) { +VOID CreateDispatchCommon(PDOKAN_IO_EVENT IoEvent, ULONG SizeOfEventInfo, BOOL UseExtraMemoryPool, BOOL ClearNonPoolBuffer) { assert(IoEvent != NULL); assert(IoEvent->EventResult == NULL && IoEvent->EventResultSize == 0); @@ -906,15 +921,38 @@ VOID CreateDispatchCommon(PDOKAN_IO_EVENT IoEvent, ULONG SizeOfEventInfo, BOOL C IoEvent->EventResultSize = DOKAN_EVENT_INFO_DEFAULT_SIZE; IoEvent->PoolAllocated = TRUE; } else { - IoEvent->EventResultSize = - DispatchGetEventInformationLength(SizeOfEventInfo); - IoEvent->EventResult = (PEVENT_INFORMATION)malloc(IoEvent->EventResultSize); - if (!IoEvent->EventResult) { - return; + if (UseExtraMemoryPool) { + if (SizeOfEventInfo <= (16 * 1024)) { + IoEvent->EventResult = Pop16KEventResult(); + IoEvent->EventResultSize = DOKAN_EVENT_INFO_16K_SIZE; + IoEvent->PoolAllocated = TRUE; + } else if (SizeOfEventInfo <= (32 * 1024)) { + IoEvent->EventResult = Pop32KEventResult(); + IoEvent->EventResultSize = DOKAN_EVENT_INFO_32K_SIZE; + IoEvent->PoolAllocated = TRUE; + } else if (SizeOfEventInfo <= (64 * 1024)) { + IoEvent->EventResult = Pop64KEventResult(); + IoEvent->EventResultSize = DOKAN_EVENT_INFO_64K_SIZE; + IoEvent->PoolAllocated = TRUE; + } else if (SizeOfEventInfo <= (128 * 1024)) { + IoEvent->EventResult = Pop128KEventResult(); + IoEvent->EventResultSize = DOKAN_EVENT_INFO_128K_SIZE; + IoEvent->PoolAllocated = TRUE; + } + } + if (IoEvent->EventResult == NULL) { + IoEvent->EventResultSize = + DispatchGetEventInformationLength(SizeOfEventInfo); + IoEvent->EventResult = + (PEVENT_INFORMATION)malloc(IoEvent->EventResultSize); + if (!IoEvent->EventResult) { + return; + } + ZeroMemory(IoEvent->EventResult, + ClearNonPoolBuffer + ? IoEvent->EventResultSize + : FIELD_OFFSET(EVENT_INFORMATION, Buffer[0])); } - ZeroMemory(IoEvent->EventResult, - ClearBuffer ? IoEvent->EventResultSize - : FIELD_OFFSET(EVENT_INFORMATION, Buffer[0])); } assert(IoEvent->EventResult && IoEvent->EventResultSize >= diff --git a/dokan/dokan_pool.c b/dokan/dokan_pool.c index c89640af..1855622c 100644 --- a/dokan/dokan_pool.c +++ b/dokan/dokan_pool.c @@ -27,6 +27,7 @@ with this program. If not, see . #define DOKAN_IO_BATCH_POOL_SIZE 1024 #define DOKAN_IO_EVENT_POOL_SIZE 1024 +#define DOKAN_IO_EXTRA_EVENT_POOL_SIZE 128 #define DOKAN_DIRECTORY_LIST_POOL_SIZE 128 // Global thread pool @@ -42,6 +43,18 @@ CRITICAL_SECTION g_IoEventBufferCriticalSection; PDOKAN_VECTOR g_EventResultPool = NULL; CRITICAL_SECTION g_EventResultCriticalSection; +PDOKAN_VECTOR g_16KEventResultPool = NULL; +CRITICAL_SECTION g_16KEventResultCriticalSection; + +PDOKAN_VECTOR g_32KEventResultPool = NULL; +CRITICAL_SECTION g_32KEventResultCriticalSection; + +PDOKAN_VECTOR g_64KEventResultPool = NULL; +CRITICAL_SECTION g_64KEventResultCriticalSection; + +PDOKAN_VECTOR g_128KEventResultPool = NULL; +CRITICAL_SECTION g_128KEventResultCriticalSection; + PDOKAN_VECTOR g_FileInfoPool = NULL; CRITICAL_SECTION g_FileInfoCriticalSection; @@ -63,6 +76,14 @@ int InitializePool() { 0x80000400); (void)InitializeCriticalSectionAndSpinCount(&g_EventResultCriticalSection, 0x80000400); + (void)InitializeCriticalSectionAndSpinCount(&g_16KEventResultCriticalSection, + 0x80000400); + (void)InitializeCriticalSectionAndSpinCount(&g_32KEventResultCriticalSection, + 0x80000400); + (void)InitializeCriticalSectionAndSpinCount(&g_64KEventResultCriticalSection, + 0x80000400); + (void)InitializeCriticalSectionAndSpinCount(&g_128KEventResultCriticalSection, + 0x80000400); (void)InitializeCriticalSectionAndSpinCount(&g_FileInfoCriticalSection, 0x80000400); (void)InitializeCriticalSectionAndSpinCount(&g_DirectoryListCriticalSection, @@ -87,6 +108,14 @@ int InitializePool() { DokanVector_AllocWithCapacity(sizeof(PVOID), DOKAN_IO_EVENT_POOL_SIZE); g_EventResultPool = DokanVector_AllocWithCapacity(sizeof(PVOID), DOKAN_IO_EVENT_POOL_SIZE); + g_16KEventResultPool = DokanVector_AllocWithCapacity( + sizeof(PVOID), DOKAN_IO_EXTRA_EVENT_POOL_SIZE); + g_32KEventResultPool = DokanVector_AllocWithCapacity( + sizeof(PVOID), DOKAN_IO_EXTRA_EVENT_POOL_SIZE); + g_64KEventResultPool = DokanVector_AllocWithCapacity( + sizeof(PVOID), DOKAN_IO_EXTRA_EVENT_POOL_SIZE); + g_128KEventResultPool = DokanVector_AllocWithCapacity( + sizeof(PVOID), DOKAN_IO_EXTRA_EVENT_POOL_SIZE); g_FileInfoPool = DokanVector_AllocWithCapacity(sizeof(PVOID), DOKAN_IO_EVENT_POOL_SIZE); g_DirectoryListPool = DokanVector_AllocWithCapacity( @@ -144,6 +173,62 @@ VOID CleanupPool() { DeleteCriticalSection(&g_EventResultCriticalSection); } + { + EnterCriticalSection(&g_16KEventResultCriticalSection); + { + for (size_t i = 0; i < DokanVector_GetCount(g_16KEventResultPool); ++i) { + FreeEventResult(*(PEVENT_INFORMATION *)DokanVector_GetItem( + g_16KEventResultPool, i)); + } + DokanVector_Free(g_16KEventResultPool); + g_16KEventResultPool = NULL; + } + LeaveCriticalSection(&g_16KEventResultCriticalSection); + DeleteCriticalSection(&g_16KEventResultCriticalSection); + } + + { + EnterCriticalSection(&g_32KEventResultCriticalSection); + { + for (size_t i = 0; i < DokanVector_GetCount(g_32KEventResultPool); ++i) { + FreeEventResult(*(PEVENT_INFORMATION *)DokanVector_GetItem( + g_32KEventResultPool, i)); + } + DokanVector_Free(g_32KEventResultPool); + g_32KEventResultPool = NULL; + } + LeaveCriticalSection(&g_32KEventResultCriticalSection); + DeleteCriticalSection(&g_32KEventResultCriticalSection); + } + + { + EnterCriticalSection(&g_64KEventResultCriticalSection); + { + for (size_t i = 0; i < DokanVector_GetCount(g_64KEventResultPool); ++i) { + FreeEventResult(*(PEVENT_INFORMATION *)DokanVector_GetItem( + g_64KEventResultPool, i)); + } + DokanVector_Free(g_64KEventResultPool); + g_64KEventResultPool = NULL; + } + LeaveCriticalSection(&g_64KEventResultCriticalSection); + DeleteCriticalSection(&g_64KEventResultCriticalSection); + } + + { + EnterCriticalSection(&g_128KEventResultCriticalSection); + { + for (size_t i = 0; i < DokanVector_GetCount(g_128KEventResultPool); ++i) { + FreeEventResult(*(PEVENT_INFORMATION *)DokanVector_GetItem( + g_128KEventResultPool, i)); + } + DokanVector_Free(g_128KEventResultPool); + g_128KEventResultPool = NULL; + } + LeaveCriticalSection(&g_128KEventResultCriticalSection); + DeleteCriticalSection(&g_128KEventResultCriticalSection); + } + //////////////////// File info object pool //////////////////// { EnterCriticalSection(&g_FileInfoCriticalSection); @@ -193,7 +278,8 @@ PDOKAN_IO_BATCH PopIoBatchBuffer() { ioBatch = (PDOKAN_IO_BATCH)malloc(DOKAN_IO_BATCH_SIZE); } if (ioBatch) { - RtlZeroMemory(ioBatch, DOKAN_IO_BATCH_SIZE); + RtlZeroMemory(ioBatch, FIELD_OFFSET(DOKAN_IO_BATCH, EventContext)); + ioBatch->PoolAllocated = TRUE; } return ioBatch; } @@ -211,6 +297,10 @@ VOID PushIoBatchBuffer(PDOKAN_IO_BATCH IoBatch) { if (currentEventContextBatchCount > 0) { return; } + if (!IoBatch->PoolAllocated) { + FreeIoBatchBuffer(IoBatch); + return; + } EnterCriticalSection(&g_IoBatchBufferCriticalSection); { if (DokanVector_GetCount(g_IoBatchBufferPool) < DOKAN_IO_BATCH_POOL_SIZE) { @@ -302,6 +392,154 @@ VOID PushEventResult(PEVENT_INFORMATION EventResult) { } } +/////////////////// EVENT_INFORMATION 16K /////////////////// +PEVENT_INFORMATION Pop16KEventResult() { + PEVENT_INFORMATION eventResult = NULL; + EnterCriticalSection(&g_16KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_16KEventResultPool) > 0) { + eventResult = + *(PEVENT_INFORMATION *)DokanVector_GetLastItem(g_16KEventResultPool); + DokanVector_PopBack(g_16KEventResultPool); + } + } + LeaveCriticalSection(&g_16KEventResultCriticalSection); + if (!eventResult) { + eventResult = (PEVENT_INFORMATION)malloc(DOKAN_EVENT_INFO_16K_SIZE); + } + if (eventResult) { + RtlZeroMemory(eventResult, FIELD_OFFSET(EVENT_INFORMATION, Buffer)); + } + return eventResult; +} + +VOID Push16KEventResult(PEVENT_INFORMATION EventResult) { + assert(EventResult); + EnterCriticalSection(&g_16KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_16KEventResultPool) < + DOKAN_IO_EXTRA_EVENT_POOL_SIZE) { + DokanVector_PushBack(g_16KEventResultPool, &EventResult); + EventResult = NULL; + } + } + LeaveCriticalSection(&g_16KEventResultCriticalSection); + if (EventResult) { + FreeEventResult(EventResult); + } +} + +/////////////////// EVENT_INFORMATION 32K /////////////////// +PEVENT_INFORMATION Pop32KEventResult() { + PEVENT_INFORMATION eventResult = NULL; + EnterCriticalSection(&g_32KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_32KEventResultPool) > 0) { + eventResult = + *(PEVENT_INFORMATION *)DokanVector_GetLastItem(g_32KEventResultPool); + DokanVector_PopBack(g_32KEventResultPool); + } + } + LeaveCriticalSection(&g_32KEventResultCriticalSection); + if (!eventResult) { + eventResult = (PEVENT_INFORMATION)malloc(DOKAN_EVENT_INFO_32K_SIZE); + } + if (eventResult) { + RtlZeroMemory(eventResult, FIELD_OFFSET(EVENT_INFORMATION, Buffer)); + } + return eventResult; +} + +VOID Push32KEventResult(PEVENT_INFORMATION EventResult) { + assert(EventResult); + EnterCriticalSection(&g_32KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_32KEventResultPool) < + DOKAN_IO_EXTRA_EVENT_POOL_SIZE) { + DokanVector_PushBack(g_32KEventResultPool, &EventResult); + EventResult = NULL; + } + } + LeaveCriticalSection(&g_32KEventResultCriticalSection); + if (EventResult) { + FreeEventResult(EventResult); + } +} + +/////////////////// EVENT_INFORMATION 64K /////////////////// +PEVENT_INFORMATION Pop64KEventResult() { + PEVENT_INFORMATION eventResult = NULL; + EnterCriticalSection(&g_64KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_64KEventResultPool) > 0) { + eventResult = + *(PEVENT_INFORMATION *)DokanVector_GetLastItem(g_64KEventResultPool); + DokanVector_PopBack(g_64KEventResultPool); + } + } + LeaveCriticalSection(&g_64KEventResultCriticalSection); + if (!eventResult) { + eventResult = (PEVENT_INFORMATION)malloc(DOKAN_EVENT_INFO_64K_SIZE); + } + if (eventResult) { + RtlZeroMemory(eventResult, FIELD_OFFSET(EVENT_INFORMATION, Buffer)); + } + return eventResult; +} + +VOID Push64KEventResult(PEVENT_INFORMATION EventResult) { + assert(EventResult); + EnterCriticalSection(&g_64KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_64KEventResultPool) < + DOKAN_IO_EXTRA_EVENT_POOL_SIZE) { + DokanVector_PushBack(g_64KEventResultPool, &EventResult); + EventResult = NULL; + } + } + LeaveCriticalSection(&g_64KEventResultCriticalSection); + if (EventResult) { + FreeEventResult(EventResult); + } +} + +/////////////////// EVENT_INFORMATION 128K /////////////////// +PEVENT_INFORMATION Pop128KEventResult() { + PEVENT_INFORMATION eventResult = NULL; + EnterCriticalSection(&g_128KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_128KEventResultPool) > 0) { + eventResult = + *(PEVENT_INFORMATION *)DokanVector_GetLastItem(g_128KEventResultPool); + DokanVector_PopBack(g_128KEventResultPool); + } + } + LeaveCriticalSection(&g_128KEventResultCriticalSection); + if (!eventResult) { + eventResult = (PEVENT_INFORMATION)malloc(DOKAN_EVENT_INFO_128K_SIZE); + } + if (eventResult) { + RtlZeroMemory(eventResult, FIELD_OFFSET(EVENT_INFORMATION, Buffer)); + } + return eventResult; +} + +VOID Push128KEventResult(PEVENT_INFORMATION EventResult) { + assert(EventResult); + EnterCriticalSection(&g_128KEventResultCriticalSection); + { + if (DokanVector_GetCount(g_128KEventResultPool) < + DOKAN_IO_EXTRA_EVENT_POOL_SIZE) { + DokanVector_PushBack(g_128KEventResultPool, &EventResult); + EventResult = NULL; + } + } + LeaveCriticalSection(&g_128KEventResultCriticalSection); + if (EventResult) { + FreeEventResult(EventResult); + } +} + /////////////////// DOKAN_OPEN_INFO /////////////////// PDOKAN_OPEN_INFO PopFileOpenInfo() { PDOKAN_OPEN_INFO fileInfo = NULL; diff --git a/dokan/dokan_pool.h b/dokan/dokan_pool.h index 96fd69b8..6084e0dc 100644 --- a/dokan/dokan_pool.h +++ b/dokan/dokan_pool.h @@ -32,6 +32,15 @@ with this program. If not, see . ((SIZE_T)(FIELD_OFFSET(DOKAN_IO_BATCH, EventContext)) + \ BATCH_EVENT_CONTEXT_SIZE) +#define DOKAN_EVENT_INFO_16K_SIZE \ + (FIELD_OFFSET(EVENT_INFORMATION, Buffer) + (16 * 1024)) +#define DOKAN_EVENT_INFO_32K_SIZE \ + (FIELD_OFFSET(EVENT_INFORMATION, Buffer) + (32 * 1024)) +#define DOKAN_EVENT_INFO_64K_SIZE \ + (FIELD_OFFSET(EVENT_INFORMATION, Buffer) + (64 * 1024)) +#define DOKAN_EVENT_INFO_128K_SIZE \ + (FIELD_OFFSET(EVENT_INFORMATION, Buffer) + (128 * 1024)) + PTP_POOL GetThreadPool(); int InitializePool(); VOID CleanupPool(); @@ -47,6 +56,15 @@ PEVENT_INFORMATION PopEventResult(); VOID PushEventResult(PEVENT_INFORMATION EventResult); VOID FreeEventResult(PEVENT_INFORMATION EventResult); +PEVENT_INFORMATION Pop16KEventResult(); +VOID Push16KEventResult(PEVENT_INFORMATION EventResult); +PEVENT_INFORMATION Pop32KEventResult(); +VOID Push32KEventResult(PEVENT_INFORMATION EventResult); +PEVENT_INFORMATION Pop64KEventResult(); +VOID Push64KEventResult(PEVENT_INFORMATION EventResult); +PEVENT_INFORMATION Pop128KEventResult(); +VOID Push128KEventResult(PEVENT_INFORMATION EventResult); + PDOKAN_OPEN_INFO PopFileOpenInfo(); VOID PushFileOpenInfo(PDOKAN_OPEN_INFO FileInfo); VOID FreeFileOpenInfo(PDOKAN_OPEN_INFO FileInfo); diff --git a/dokan/dokani.h b/dokan/dokani.h index 15c36974..0a8ad33e 100644 --- a/dokan/dokani.h +++ b/dokan/dokani.h @@ -138,6 +138,11 @@ typedef struct _DOKAN_IO_BATCH { DWORD NumberOfBytesTransferred; /** Whether it is used by the Main pull thread that wait indefinitely in kernel compared to volatile pool threads */ BOOL MainPullThread; + /** + * Whether this object was allocated from the memory pool. + * Large Write events will allocate a specific buffer that will not come from the memory pool. + */ + BOOL PoolAllocated; /** * Number of actual EVENT_CONTEXT stored in EventContext. * This is used as a shared buffer counter that is decremented when an event is processed. @@ -213,7 +218,7 @@ BOOL IsMountPointDriveLetter(LPCWSTR mountPoint); VOID EventCompletion(PDOKAN_IO_EVENT EventInfo); VOID CreateDispatchCommon(PDOKAN_IO_EVENT IoEvent, ULONG SizeOfEventInfo, - BOOL ClearBuffer); + BOOL UseExtraMemoryPool, BOOL ClearNonPoolBuffer); VOID DispatchDirectoryInformation(PDOKAN_IO_EVENT IoEvent); diff --git a/dokan/fileinfo.c b/dokan/fileinfo.c index fff8e49c..55740a67 100644 --- a/dokan/fileinfo.c +++ b/dokan/fileinfo.c @@ -472,7 +472,8 @@ VOID DispatchQueryInformation(PDOKAN_IO_EVENT IoEvent) { CreateDispatchCommon(IoEvent, IoEvent->EventContext->Operation.File.BufferLength, - /*ClearBuffer=*/TRUE); + /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); if (IoEvent->EventContext->Operation.File.FileInformationClass == FileStreamInformation) { diff --git a/dokan/flush.c b/dokan/flush.c index e60acf4c..4d599ce3 100644 --- a/dokan/flush.c +++ b/dokan/flush.c @@ -27,7 +27,8 @@ VOID DispatchFlush(PDOKAN_IO_EVENT IoEvent) { CheckFileName(IoEvent->EventContext->Operation.Flush.FileName); - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); DbgPrint("###Flush file handle = 0x%p, eventID = %04d, event Info = 0x%p\n", IoEvent->DokanOpenInfo, diff --git a/dokan/lock.c b/dokan/lock.c index 255f1ebb..f70c0b1a 100644 --- a/dokan/lock.c +++ b/dokan/lock.c @@ -28,7 +28,8 @@ VOID DispatchLock(PDOKAN_IO_EVENT IoEvent) { CheckFileName(IoEvent->EventContext->Operation.Lock.FileName); - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); DbgPrint("###Lock file handle = 0x%p, eventID = %04d, event Info = 0x%p\n", IoEvent->DokanOpenInfo, diff --git a/dokan/read.c b/dokan/read.c index cab5b018..0ee3d9b8 100644 --- a/dokan/read.c +++ b/dokan/read.c @@ -30,7 +30,8 @@ VOID DispatchRead(PDOKAN_IO_EVENT IoEvent) { CreateDispatchCommon(IoEvent, IoEvent->EventContext->Operation.Read.BufferLength, - /*ClearBuffer=*/FALSE); + /*UseExtraMemoryPool=*/TRUE, + /*ClearNonPoolBuffer=*/FALSE); DbgPrint("###Read file handle = 0x%p, eventID = %04d, event Info = 0x%p\n", IoEvent->DokanOpenInfo, diff --git a/dokan/security.c b/dokan/security.c index 6895a95a..ad57a628 100644 --- a/dokan/security.c +++ b/dokan/security.c @@ -135,7 +135,8 @@ VOID DispatchQuerySecurity(PDOKAN_IO_EVENT IoEvent) { CreateDispatchCommon(IoEvent, IoEvent->EventContext->Operation.Security.BufferLength, - /*ClearBuffer=*/TRUE); + /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); DbgPrint("###GetFileSecurity file handle = 0x%p, eventID = %04d, event Info " "= 0x%p\n", @@ -185,7 +186,8 @@ VOID DispatchSetSecurity(PDOKAN_IO_EVENT IoEvent) { CheckFileName(IoEvent->EventContext->Operation.SetSecurity.FileName); - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); DbgPrint( "###SetSecurity file handle = 0x%p, eventID = %04d, event Info = 0x%p\n", diff --git a/dokan/setfile.c b/dokan/setfile.c index bc35383e..5ec11e60 100644 --- a/dokan/setfile.c +++ b/dokan/setfile.c @@ -211,9 +211,11 @@ VOID DispatchSetInformation(PDOKAN_IO_EVENT IoEvent) { IoEvent->EventContext->Operation.SetFile .BufferOffset); CreateDispatchCommon(IoEvent, renameInfo->FileNameLength, - /*ClearBuffer=*/TRUE); + /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); } else { - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); } CheckFileName(IoEvent->EventContext->Operation.SetFile.FileName); diff --git a/dokan/volume.c b/dokan/volume.c index 6030cdda..61a0b689 100644 --- a/dokan/volume.c +++ b/dokan/volume.c @@ -314,7 +314,8 @@ DokanFsFullSizeInformation(PEVENT_INFORMATION EventInfo, VOID DispatchQueryVolumeInformation(PDOKAN_IO_EVENT IoEvent) { CreateDispatchCommon(IoEvent, IoEvent->EventContext->Operation.Volume.BufferLength, - /*ClearBuffer=*/TRUE); + /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); DbgPrint("###QueryVolumeInfo file handle = 0x%p, eventID = %04d, event Info " "= 0x%p\n", diff --git a/dokan/write.c b/dokan/write.c index 937e9962..cc4d95b9 100644 --- a/dokan/write.c +++ b/dokan/write.c @@ -29,11 +29,16 @@ with this program. If not, see . DWORD SendWriteRequest(PDOKAN_IO_EVENT IoEvent, ULONG WriteEventContextLength, PDOKAN_IO_BATCH *WriteIoBatch) { DWORD WrittenLength = 0; - *WriteIoBatch = malloc((SIZE_T)FIELD_OFFSET(DOKAN_IO_BATCH, EventContext) + - WriteEventContextLength); - if (!*WriteIoBatch) { - DokanDbgPrintW(L"Dokan Error: Failed to allocate IO event buffer.\n"); - return ERROR_NO_SYSTEM_RESOURCES; + if (WriteEventContextLength <= BATCH_EVENT_CONTEXT_SIZE) { + *WriteIoBatch = PopIoBatchBuffer(); + } else { + *WriteIoBatch = malloc((SIZE_T)FIELD_OFFSET(DOKAN_IO_BATCH, EventContext) + + WriteEventContextLength); + if (!*WriteIoBatch) { + DokanDbgPrintW(L"Dokan Error: Failed to allocate IO event buffer.\n"); + return ERROR_NO_SYSTEM_RESOURCES; + } + (*WriteIoBatch)->PoolAllocated = FALSE; } if (!DeviceIoControl( @@ -56,7 +61,8 @@ VOID DispatchWrite(PDOKAN_IO_EVENT IoEvent) { ULONG writtenLength = 0; NTSTATUS status; - CreateDispatchCommon(IoEvent, 0, /*ClearBuffer=*/TRUE); + CreateDispatchCommon(IoEvent, 0, /*UseExtraMemoryPool=*/FALSE, + /*ClearNonPoolBuffer=*/TRUE); CheckFileName(IoEvent->EventContext->Operation.Write.FileName); DbgPrint( @@ -117,7 +123,7 @@ VOID DispatchWrite(PDOKAN_IO_EVENT IoEvent) { } if (writeIoBatch != IoEvent->IoBatch) { - free(writeIoBatch); + PushIoBatchBuffer(writeIoBatch); } EventCompletion(IoEvent);