NTSTATUS LwIoFuseUnlink( const char* pszPath ) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus = {0}; IO_FILE_HANDLE handle = NULL; PIO_FUSE_CONTEXT pFuseContext = NULL; IO_FILE_NAME filename = {0}; pFuseContext = LwIoFuseGetContext(); status = LwIoFuseGetNtFilename( pFuseContext, pszPath, &filename); BAIL_ON_NT_STATUS(status); status = LwNtCreateFile( &handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ &filename, /* Filename */ NULL, /* Security descriptor */ NULL, /* Security QOS */ DELETE, /* Desired access mask */ 0, /* Allocation size */ 0, /* File attributes */ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* Share access */ FILE_OPEN, /* Create disposition */ FILE_DELETE_ON_CLOSE, /* Create options */ NULL, /* EA buffer */ 0, /* EA length */ NULL, /* ECP list */ NULL); BAIL_ON_NT_STATUS(status); cleanup: if (handle) { LwNtCloseFile(handle); } RTL_UNICODE_STRING_FREE(&filename.Name); return status; error: goto cleanup; }
NTSTATUS LwIoFuseRename( const char* pszOldPath, const char* pszNewPath ) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus = {0}; IO_FILE_HANDLE handle = NULL; PIO_FUSE_CONTEXT pFuseContext = NULL; IO_FILE_NAME filename = {0}; PFILE_RENAME_INFORMATION pRenameInfo = NULL; PWSTR pwszNewPath = NULL; size_t newPathLength = 0; pFuseContext = LwIoFuseGetContext(); status = LwIoFuseGetDriverRelativePath( pFuseContext, pszNewPath, &pwszNewPath); BAIL_ON_NT_STATUS(status); newPathLength = LwRtlWC16StringNumChars(pwszNewPath); status = RTL_ALLOCATE( &pRenameInfo, FILE_RENAME_INFORMATION, sizeof(*pRenameInfo) + (newPathLength + 1) * sizeof(WCHAR)); BAIL_ON_NT_STATUS(status); pRenameInfo->ReplaceIfExists = TRUE; pRenameInfo->RootDirectory = NULL; pRenameInfo->FileNameLength = newPathLength * sizeof(WCHAR); memcpy(pRenameInfo->FileName, pwszNewPath, newPathLength * sizeof(WCHAR)); status = LwIoFuseGetNtFilename( pFuseContext, pszOldPath, &filename); BAIL_ON_NT_STATUS(status); status = LwNtCreateFile( &handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ &filename, /* Filename */ NULL, /* Security descriptor */ NULL, /* Security QOS */ DELETE, /* Desired access mask */ 0, /* Allocation size */ 0, /* File attributes */ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* Share access */ FILE_OPEN, /* Create disposition */ 0, /* Create options */ NULL, /* EA buffer */ 0, /* EA length */ NULL, /* ECP list */ NULL); BAIL_ON_NT_STATUS(status); status = LwNtSetInformationFile( handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ pRenameInfo, /* File information */ sizeof(*pRenameInfo) + (newPathLength + 1) * sizeof(WCHAR), /* File information size */ FileRenameInformation); /* Information class */ BAIL_ON_NT_STATUS(status); cleanup: if (handle) { LwNtCloseFile(handle); } RTL_UNICODE_STRING_FREE(&filename.Name); RTL_FREE(&pwszNewPath); RTL_FREE(&pRenameInfo); return status; error: goto cleanup; }
NTSTATUS LwIoFuseCreate( const char* pszPath, mode_t mode, struct fuse_file_info* pFileInfo ) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus = {0}; IO_FILE_HANDLE handle = NULL; PIO_FUSE_CONTEXT pFuseContext = NULL; IO_FILE_NAME filename = {0}; /* We only support creating regular files */ if (!S_ISREG(mode)) { status = STATUS_NOT_SUPPORTED; BAIL_ON_NT_STATUS(status); } pFuseContext = LwIoFuseGetContext(); status = LwIoFuseGetNtFilename( pFuseContext, pszPath, &filename); BAIL_ON_NT_STATUS(status); status = LwNtCreateFile( &handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ &filename, /* Filename */ NULL, /* Security descriptor */ NULL, /* Security QOS */ FILE_WRITE_DATA, /* Desired access mask */ 0, /* Allocation size */ 0, /* File attributes */ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* Share access */ FILE_CREATE, /* Create disposition */ FILE_NON_DIRECTORY_FILE, /* Create options */ NULL, /* EA buffer */ 0, /* EA length */ NULL, /* ECP list */ NULL); BAIL_ON_NT_STATUS(status); pFileInfo->fh = NT_TO_FUSE_FH(handle); cleanup: RTL_UNICODE_STRING_FREE(&filename.Name); return status; error: if (handle) { LwNtCloseFile(handle); } goto cleanup; }
NTSTATUS LwioRemoteOpenFile( IN PCSTR pszFileName, IN ULONG ulDesiredAccess, IN ULONG ulShareAccess, IN ULONG ulCreateDisposition, IN ULONG ulCreateOptions, OUT PIO_FILE_HANDLE phFile ) { NTSTATUS status = STATUS_SUCCESS; IO_FILE_NAME filename = {0}; IO_FILE_HANDLE handle = NULL; IO_STATUS_BLOCK ioStatus ; PSTR pszRemoteFileName = NULL; BAIL_ON_NULL_POINTER(pszFileName); status = LwRtlCStringAllocatePrintf( &pszRemoteFileName, "/rdr%s", !strncmp(pszFileName, "//", sizeof("//")-1) ? pszFileName+1 : pszFileName); BAIL_ON_NT_STATUS(status); status = LwRtlUnicodeStringAllocateFromCString( &filename.Name, pszRemoteFileName); BAIL_ON_NT_STATUS(status); status = LwNtCreateFile( &handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ &filename, /* Filename */ NULL, /* Security descriptor */ NULL, /* Security QOS */ ulDesiredAccess, /* Desired access mask */ 0, /* Allocation size */ 0, /* File attributes */ ulShareAccess, /* Share access */ ulCreateDisposition, /* Create disposition */ ulCreateOptions, /* Create options */ NULL, /* EA buffer */ 0, /* EA length */ NULL, /* ECP list */ NULL); BAIL_ON_NT_STATUS(status); *phFile = handle; cleanup: RTL_FREE(&pszRemoteFileName); return status; error: *phFile = NULL; goto cleanup; }
NTSTATUS LwIoFuseTruncate( const char* pszPath, off_t size ) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus = {0}; IO_FILE_HANDLE handle = NULL; PIO_FUSE_CONTEXT pFuseContext = NULL; FILE_END_OF_FILE_INFORMATION endOfFileInfo = {0}; IO_FILE_NAME filename = {0}; endOfFileInfo.EndOfFile = (LONG64) size; pFuseContext = LwIoFuseGetContext(); status = LwIoFuseGetNtFilename( pFuseContext, pszPath, &filename); BAIL_ON_NT_STATUS(status); status = LwNtCreateFile( &handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ &filename, /* Filename */ NULL, /* Security descriptor */ NULL, /* Security QOS */ FILE_WRITE_DATA, /* Desired access mask */ 0, /* Allocation size */ 0, /* File attributes */ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* Share access */ FILE_OPEN, /* Create disposition */ FILE_NON_DIRECTORY_FILE, /* Create options */ NULL, /* EA buffer */ 0, /* EA length */ NULL, /* ECP list */ NULL); BAIL_ON_NT_STATUS(status); status = LwNtSetInformationFile( handle, /* File handle */ NULL, /* Async control block */ &ioStatus, /* IO status block */ &endOfFileInfo, /* File information */ sizeof(endOfFileInfo), /* File information size */ FileEndOfFileInformation); /* Information class */ BAIL_ON_NT_STATUS(status); cleanup: if (handle) { LwNtCloseFile(handle); } RTL_UNICODE_STRING_FREE(&filename.Name); return status; error: goto cleanup; }
LW_NTSTATUS LwIoSetRdrDomainHints( LW_PWSTR* ppwszDomains, ULONG ulCount ) { NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK ioStatus = {0}; WCHAR wszRdrPath[] = {'\\', 'r', 'd', 'r', '\0'}; UNICODE_STRING rdrPath = LW_RTL_CONSTANT_STRING(wszRdrPath); IO_FILE_NAME fileName = {0}; IO_FILE_HANDLE hFile = NULL; PWSTR pwszBuffer = NULL; ULONG ulLength = 0; ULONG ulIndex = 0; ULONG ulOffset = 0; ULONG ulStrLen = 0; for (ulIndex = 0; ulIndex < ulCount; ulIndex++) { ulLength += (LwRtlWC16StringNumChars(ppwszDomains[ulIndex]) + 1) * sizeof(WCHAR); } status = RTL_ALLOCATE(&pwszBuffer, WCHAR, ulLength); BAIL_ON_NT_STATUS(status); for (ulIndex = 0; ulIndex < ulCount; ulIndex++) { ulStrLen = (LwRtlWC16StringNumChars(ppwszDomains[ulIndex]) + 1) * sizeof(WCHAR); memcpy((PBYTE) pwszBuffer + ulOffset, ppwszDomains[ulIndex], ulStrLen); ulOffset += ulStrLen; } fileName.Name = rdrPath; status = LwNtCreateFile( &hFile, NULL, &ioStatus, &fileName, NULL, NULL, FILE_GENERIC_WRITE, 0, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0, NULL, NULL); BAIL_ON_NT_STATUS(status); status = LwNtDeviceIoControlFile( hFile, NULL, &ioStatus, RDR_DEVCTL_SET_DOMAIN_HINTS, pwszBuffer, ulLength, NULL, 0); BAIL_ON_NT_STATUS(status); cleanup: RTL_FREE(&pwszBuffer); if (hFile) { LwNtCloseFile(hFile); } return status; error: goto cleanup; }