s_hqyao
驱动牛犊
驱动牛犊
  • 注册日期2006-08-21
  • 最后登录2009-12-03
  • 粉丝0
  • 关注0
  • 积分191分
  • 威望30点
  • 贡献值0点
  • 好评度19点
  • 原创分1分
  • 专家分0分
阅读:3718回复:4

文件名的短路径转换成长路径

楼主#
更多 发布于:2007-08-07 13:31
NTSTATUS
SFilterShortNameToLongName(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PNAME_CONTROL FileNameCtrl
    )                              
{
    PWSTR pos1 = NULL, pos2 = NULL, posShadow = NULL;
    PWSTR pFileName = NULL, pFileNameOutput = NULL;
    HANDLE FileHandle = NULL;
    HANDLE  hEvent = NULL;
    PFILE_BOTH_DIR_INFORMATION pBufQuery = NULL;
    PENCRYPT_DEVICE_EXTENSION DevExtReal = NULL;
    PENCRYPT_DEVICE_EXTENSION DevExtShadow = NULL;
    NTSTATUS Status = STATUS_SUCCESS;

    SFilterPrintUnicodeString("SFilter! EncryptShortName(%s) Entering......\n", FileNameCtrl->Name.Buffer);
    
    __try {

        DevExtReal = (PENCRYPT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        ASSERT(DevExtReal->RelatedDeviceObject != NULL);
        DevExtShadow = (PENCRYPT_DEVICE_EXTENSION)DevExtReal->RelatedDeviceObject->DeviceExtension;
        
        __try {

            UNICODE_STRING objName, queryName;
            OBJECT_ATTRIBUTES objAttributes;
            IO_STATUS_BLOCK IoStatus;
            WCHAR oldChar;
            ULONG bufQueryLength;
            BOOLEAN bAppendBias;

            pFileName = ExAllocateFromPagedLookasideList(&gMaxNameLookasideList);
            if (pFileName == NULL){
                
                KdPrint(("SFilter! SFilterShortNameToLongName call ExAllocateFromPagedLookasideList failed!

STATUS_INSUFFICIENT_RESOURCES\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                __leave;
            }

            pFileNameOutput = ExAllocateFromPagedLookasideList(&gMaxNameLookasideList);
            if (pFileNameOutput == NULL) {
            
                KdPrint(("SFilter! SFilterShortNameToLongName call ExAllocateFromPagedLookasideList failed!

STATUS_INSUFFICIENT_RESOURCES\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                __leave;
            }

            RtlStringCchCopyW(pFileNameOutput, MAX_PATH_LENGTH, FileNameCtrl->Name.Buffer);
            *(wcschr(pFileNameOutput, L'\\')+1) = UNICODE_NULL;

            Status = ZwCreateEvent(&hEvent, GENERIC_ALL, NULL, NotificationEvent, FALSE);
            if (!NT_SUCCESS(Status)) {
                
                KdPrint(("SFilter! SFilterShortNameToLongName call ZwCreateEvent failed (0x%x)\n", Status));
                __leave;
            }

            bufQueryLength = sizeof(FILE_BOTH_DIR_INFORMATION)+100; // Buffer enougth ?
            pBufQuery = ExAllocatePoolWithTag(PagedPool, bufQueryLength, ENCRYPT_POOL_TAG);
            if (pBufQuery == NULL) {
                
                KdPrint(("SFilter! SFilterShortNameToLongName call ZwCreateEvent failed ! STATUS_INSUFFICIENT_RESOURCES\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                __leave;
            }

            posShadow = pos1 = wcschr(FileNameCtrl->Name.Buffer, L'\\');
            while (pos1 != NULL && *(++pos1) != UNICODE_NULL) {
                
                RtlStringCchCopyW(pFileName, MAX_PATH_LENGTH, DevExtShadow->NLExtHeader.DeviceName.Buffer);

                oldChar = *pos1;
                *pos1 = UNICODE_NULL;
                RtlStringCchCatW(pFileName, MAX_PATH_LENGTH, posShadow);
                *pos1 = oldChar;

                RtlInitUnicodeString(&objName, pFileName);
                InitializeObjectAttributes(&objAttributes, &objName,
                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
            
                Status = ZwCreateFile(&FileHandle, FILE_READ_DATA | SYNCHRONIZE,
                    &objAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL,
                    FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

                if (!NT_SUCCESS(Status) || FileHandle == NULL) {
                    
                    KdPrint(("SFilter! SFilterShortNameToLongName call ZwCreateFile failed (0x%x)\n", Status));              

                __leave;
                }
            
                pos2 = wcschr(pos1, L'\\');
                if (pos2 != NULL) {

                    *pos2 = UNICODE_NULL;
                    RtlInitUnicodeString(&queryName, pos1);
                    *pos2 = L'\\';
                    bAppendBias = TRUE;

                } else {
                    
                    RtlInitUnicodeString(&queryName, pos1);
                    bAppendBias = FALSE;

                }    

                Status = ZwQueryDirectoryFile(FileHandle, hEvent, NULL, NULL, &IoStatus, pBufQuery, bufQueryLength,
                    FileBothDirectoryInformation, TRUE, &queryName, TRUE);

                if (Status == STATUS_PENDING) {

                    ZwWaitForSingleObject(hEvent, TRUE, NULL);
                
                } else if (!NT_SUCCESS(Status)) {

                    KdPrint(("SFilter! SFilterShortNameToLongName call ZwQueryDirectoryFile Status = 0x%x\n", Status));
                    __leave;          
                }
                
                if (!NT_SUCCESS(Status = ZwClose(FileHandle))) {
                    
                    KdPrint(("SFilter! SFilterShortNameToLongName call ZwClose(0x%x) failed (0x%x)\n", FileHandle, Status));
                    __leave;
                }

                FileHandle = NULL; // NULL again

                RtlStringCchCatNW(pFileNameOutput, MAX_PATH_LENGTH, pBufQuery->FileName, pBufQuery->FileNameLength>>1);      

        
                if (bAppendBias)
                    RtlStringCchCatW(pFileNameOutput, MAX_PATH_LENGTH, L"\\");
                
                pos1 = wcschr(pos1, L'\\'); // Next component again
            }
            
            if (Status == STATUS_SUCCESS) {

                ULONG newSize;
                RtlStringCbLengthW(pFileNameOutput, MAX_PATH_LENGTH*sizeof(WCHAR), &newSize);
                NLCheckAndGrowNameControl(FileNameCtrl, (USHORT)newSize);
                FileNameCtrl->Name.Length = (USHORT)(newSize+sizeof(WCHAR));
                RtlStringCchCopyW(FileNameCtrl->Name.Buffer, MAX_PATH_LENGTH, pFileNameOutput);
            }

        } __finally {

            if (pFileName != NULL)
                ExFreeToPagedLookasideList(&gMaxNameLookasideList, pFileName);
            
            if (pFileNameOutput != NULL)
                ExFreeToPagedLookasideList(&gMaxNameLookasideList, pFileNameOutput);

            if (FileHandle != NULL)
                ZwClose(FileHandle);

            if (hEvent != NULL)
                ZwClose(hEvent);

            if (pBufQuery != NULL)
                ExFreePoolWithTag(pBufQuery, ENCRYPT_POOL_TAG);
                
        }

    } __except (EXCEPTION_EXECUTE_HANDLER) {

        Status = GetExceptionCode();
        KdPrint(("SFilter! SFilterShortNameToLongName exception happen! exception code (0x%x)!\n", Status));

    }

    return Status;
}

1.注释较少,大家将就点看。
2.包含Shadow Device 的处理,防止IRP_MJ_CREATE的重入。
3.感谢wowocock在某个帖子中回复的提示。

最新喜欢:

znsoftznsoft
lambokini
驱动牛犊
驱动牛犊
  • 注册日期2006-10-09
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分354分
  • 威望77点
  • 贡献值1点
  • 好评度36点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-08-07 13:42
谢谢,研究下。
linuxyf
驱动小牛
驱动小牛
  • 注册日期2007-04-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望162点
  • 贡献值0点
  • 好评度161点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2007-08-10 09:24
不错啊 ,支持一下。
在孤独和无助中缓慢前行...
ddzjh
驱动牛犊
驱动牛犊
  • 注册日期2007-04-13
  • 最后登录2008-07-07
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-09-01 11:05
问一个很菜的问题:
PNAME_CONTROL
PENCRYPT_DEVICE_EXTENSION
SFilterPrintUnicodeString
gMaxNameLookasideList
NLCheckAndGrowNameControl
ENCRYPT_POOL_TAG

这些都找不到啊
hustwing
驱动牛犊
驱动牛犊
  • 注册日期2007-08-19
  • 最后登录2012-03-03
  • 粉丝0
  • 关注0
  • 积分180分
  • 威望19点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-11-23 00:25
这些函数和结构在WDK6000的例子代码sfilter中有的:)
潜龙勿用-->见龙在田-->飞龙在天-->亢龙有悔
游客

返回顶部