Skip to content

Commit

Permalink
Added a helper function for mapping kernel flags to user mode dokan-d…
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Newton authored and Keith Newton committed Oct 26, 2015
1 parent 8b09729 commit 0b90aa6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 43 deletions.
55 changes: 55 additions & 0 deletions dokan/dokan.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dokani.h"
#include "list.h"

#define DokanMapKernelBit(dest, src, userBit, kernelBit) if(((src) & (kernelBit)) == (kernelBit)) (dest) |= (userBit)

// DokanOptions->DebugMode is ON?
BOOL g_DebugMode = TRUE;

Expand Down Expand Up @@ -767,3 +769,56 @@ BOOL WINAPI DllMain(
}
return TRUE;
}

void DOKANAPI
DokanMapKernelToUserCreateFileFlags(
ULONG FileAttributes,
ULONG CreateOptions,
ULONG CreateDisposition,
DWORD *outFileAttributesAndFlags,
DWORD *outCreationDisposition)
{
if(outFileAttributesAndFlags) {

*outFileAttributesAndFlags = FileAttributes;

DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_WRITE_THROUGH, FILE_WRITE_THROUGH);
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_SEQUENTIAL_SCAN, FILE_SEQUENTIAL_ONLY);
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_RANDOM_ACCESS, FILE_RANDOM_ACCESS);
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_NO_BUFFERING, FILE_NO_INTERMEDIATE_BUFFERING);
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_OPEN_REPARSE_POINT, FILE_OPEN_REPARSE_POINT);
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_DELETE_ON_CLOSE, FILE_DELETE_ON_CLOSE);
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_BACKUP_SEMANTICS, FILE_OPEN_FOR_BACKUP_INTENT);

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
DokanMapKernelBit(*outFileAttributesAndFlags, CreateOptions, FILE_FLAG_SESSION_AWARE, FILE_SESSION_AWARE);
#endif
}

if(outCreationDisposition) {

switch(CreateDisposition) {
case FILE_CREATE:
*outCreationDisposition = CREATE_NEW;
break;
case FILE_OPEN:
*outCreationDisposition = OPEN_EXISTING;
break;
case FILE_OPEN_IF:
*outCreationDisposition = OPEN_ALWAYS;
break;
case FILE_OVERWRITE:
*outCreationDisposition = TRUNCATE_EXISTING;
break;
case FILE_SUPERSEDE:
// The documentation isn't clear on the difference between replacing a file and truncating it.
// For now we just map it to create/truncate
case FILE_OVERWRITE_IF:
*outCreationDisposition = CREATE_ALWAYS;
break;
default:
*outCreationDisposition = 0;
break;
}
}
}
2 changes: 1 addition & 1 deletion dokan/dokan.def
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ DokanSetDebugMode
DokanMountControl
DokanOpenRequestorToken
DokanRemoveMountPoint

DokanMapKernelToUserCreateFileFlags
8 changes: 8 additions & 0 deletions dokan/dokan.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ HANDLE DOKANAPI
DokanOpenRequestorToken(
PDOKAN_FILE_INFO DokanFileInfo);

void DOKANAPI
DokanMapKernelToUserCreateFileFlags(
ULONG FileAttributes,
ULONG CreateOptions,
ULONG CreateDisposition,
DWORD *outFileAttributesAndFlags,
DWORD *outCreationDisposition);

#ifdef __cplusplus
}
#endif
Expand Down
60 changes: 18 additions & 42 deletions dokan_mirror/mirror.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ THE SOFTWARE.
#include "../dokan/dokan.h"
#include "../dokan/fileinfo.h"

#define MirrorMapBit(dest, src, userBit, kernelBit) if(((src) & (kernelBit)) == (kernelBit)) (dest) |= (userBit)

BOOL g_UseStdErr;
BOOL g_DebugMode;

Expand Down Expand Up @@ -146,22 +144,13 @@ MirrorCreateFile(
HANDLE handle;
DWORD fileAttr;
NTSTATUS status = STATUS_SUCCESS;
DWORD creationDisposition = OPEN_EXISTING;
DWORD fileAttributesAndFlags = FileAttributes;

UNREFERENCED_PARAMETER(SecurityContext);
DWORD creationDisposition;
DWORD fileAttributesAndFlags;

MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_WRITE_THROUGH, FILE_WRITE_THROUGH);
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_SEQUENTIAL_SCAN, FILE_SEQUENTIAL_ONLY);
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_RANDOM_ACCESS, FILE_RANDOM_ACCESS);
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_NO_BUFFERING, FILE_NO_INTERMEDIATE_BUFFERING);
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_OPEN_REPARSE_POINT, FILE_OPEN_REPARSE_POINT);
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_DELETE_ON_CLOSE, FILE_DELETE_ON_CLOSE);
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_BACKUP_SEMANTICS, FILE_OPEN_FOR_BACKUP_INTENT);
DokanMapKernelToUserCreateFileFlags(FileAttributes, CreateOptions, CreateDisposition,
&fileAttributesAndFlags, &creationDisposition);

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
MirrorMapBit(fileAttributesAndFlags, CreateOptions, FILE_FLAG_SESSION_AWARE, FILE_SESSION_AWARE);
#endif
UNREFERENCED_PARAMETER(SecurityContext);

GetFilePath(filePath, MAX_PATH, FileName);

Expand Down Expand Up @@ -240,38 +229,25 @@ MirrorCreateFile(
MirrorCheckFlag(fileAttributesAndFlags, SECURITY_CONTEXT_TRACKING);
MirrorCheckFlag(fileAttributesAndFlags, SECURITY_EFFECTIVE_ONLY);
MirrorCheckFlag(fileAttributesAndFlags, SECURITY_SQOS_PRESENT);

switch(CreateDisposition) {
case FILE_CREATE:
creationDisposition = CREATE_NEW;
break;
case FILE_OPEN:
creationDisposition = OPEN_EXISTING;
break;
case FILE_OPEN_IF:
creationDisposition = OPEN_ALWAYS;
break;
case FILE_OVERWRITE:
creationDisposition = TRUNCATE_EXISTING;
break;
case FILE_OVERWRITE_IF:
creationDisposition = CREATE_ALWAYS;
break;
default:
// TODO: should support FILE_SUPERSEDE ?
break;
}

if(creationDisposition == CREATE_NEW)
if(creationDisposition == CREATE_NEW) {
DbgPrint(L"\tCREATE_NEW\n");
if(creationDisposition == OPEN_ALWAYS)
}
else if(creationDisposition == OPEN_ALWAYS) {
DbgPrint(L"\tOPEN_ALWAYS\n");
if(creationDisposition == CREATE_ALWAYS)
}
else if(creationDisposition == CREATE_ALWAYS) {
DbgPrint(L"\tCREATE_ALWAYS\n");
if(creationDisposition == OPEN_EXISTING)
}
else if(creationDisposition == OPEN_EXISTING) {
DbgPrint(L"\tOPEN_EXISTING\n");
if(creationDisposition == TRUNCATE_EXISTING)
}
else if(creationDisposition == TRUNCATE_EXISTING) {
DbgPrint(L"\tTRUNCATE_EXISTING\n");
}
else {
DbgPrint(L"\tUNKNOWN creationDisposition!\n");
}

handle = CreateFile(
filePath,
Expand Down

0 comments on commit 0b90aa6

Please sign in to comment.