hongpengtao
驱动小牛
驱动小牛
  • 注册日期2006-03-16
  • 最后登录2015-06-03
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望190点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
阅读:3523回复:12

请高手看看在RP_MJ_CLOSE增加文件标识的问题(附代码)

楼主#
更多 发布于:2007-05-15 14:45
代码如下
//增加文件尾部
NTSTATUS
sfAddfileCauda(IN PCWSTR FileName,
               IN UCHAR * KeyBuf,
               IN ULONG KeyBufLen,
               IN PVOID AttachedToDeviceObject)
{
    HANDLE    FileHandle = NULL;
    WCHAR    RetFileName[MAX_PATH];
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING ObjectName;

    //FILE_STANDARD_INFORMATION        fileinfo;
    FILE_END_OF_FILE_INFORMATION    fileEOFinfo;    
    LARGE_INTEGER FileEOFPos;

    IO_STATUS_BLOCK IoStatus;
    NTSTATUS Status= STATUS_SUCCESS;
    if (!(FileName && AttachedToDeviceObject))
        {
            KdPrint(("Add!(FileName && AttachedToDeviceObject)  Unsuccess\n "));
            return STATUS_INSUFFICIENT_RESOURCES;//两相参数验证出其不错
        }
    
    RetFileName[0] = L'\\';
    RetFileName[1] = L'?';
    RetFileName[2] = L'?';
    RetFileName[3] = L'\\';
    RetFileName[4] = L'\0';
    wcscat(RetFileName, FileName);

    if (RetFileName[wcslen(RetFileName) - 1] == L'\\')
        RetFileName[wcslen(RetFileName) - 1] = L'\0';

    RtlInitUnicodeString(&ObjectName, RetFileName);
    
    //Arguments:
    //    FileName - \??\x:\xxx\...\xxx.xxx
    
    
    InitializeObjectAttributes(&ObjectAttributes,
        &ObjectName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        NULL,
        NULL
        );
    Status = IoCreateFileSpecifyDeviceObjectHint(&FileHandle,
            GENERIC_WRITE|SYNCHRONIZE|GENERIC_READ,
            &ObjectAttributes,
            &IoStatus,
            NULL,
            FILE_ATTRIBUTE_NORMAL,
            0,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_NO_INTERMEDIATE_BUFFERING,
            NULL,
            0,
            CreateFileTypeNone,
            NULL,
            IO_IGNORE_SHARE_ACCESS_CHECK,
            AttachedToDeviceObject
            );                                                //打开文件
    if (NT_SUCCESS(Status))
    {
        
        FileEOFPos.LowPart = FILE_WRITE_TO_END_OF_FILE;
        FileEOFPos.HighPart = -1;
        Status = ZwWriteFile(FileHandle,
            NULL,
            NULL,
            NULL,
            &IoStatus,
            (PVOID)KeyBuf,
            FILEHEADLEN,
            &FileEOFPos,
            NULL
            );//写尾部*
        KdPrint(("sfWriteEncryptKey : %ws He's cauda is :%s\n Status :%x IoStatus.Status :%x  IoStatus.Information :%x \n",FileName,KeyBuf,Status,IoStatus.Status,IoStatus.Information));
        
        //ZwClose(FileHandle);//文件使用结束
        if(!(NT_SUCCESS(Status)))
        {    
            KdPrint(("AddZwWriteFile  Unsuccess\n "));
            return STATUS_INSUFFICIENT_RESOURCES;//得到文件长度失败
        }
        
    }
    else
    {
        KdPrint(("AddIoCreateFileSpecifyDeviceObjectHint Unsuccess\n "));
        return STATUS_INSUFFICIENT_RESOURCES;//打开文件失败
    }
    return Status;
}
我在RP_MJ_CLOSE完程以后调有以上代码
时而可用时而不可以
不能用时是在ZwWriteFile里出的错
返可代码是c0000002STATUS_NOT_IMPLEMENTED
请问大牛们怎么样保证ZwWriteFile被正确运行
万分感谢
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
沙发#
发布于:2007-05-15 15:28
IoCreateFileSpecifyDeviceObjectHint只支持XP以上,可以直接发IRP来处理!
人总在矛盾中徘徊。。。
hongpengtao
驱动小牛
驱动小牛
  • 注册日期2006-03-16
  • 最后登录2015-06-03
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望190点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-05-15 16:02
知道啊
我没有在2k下使用啊
hongpengtao
驱动小牛
驱动小牛
  • 注册日期2006-03-16
  • 最后登录2015-06-03
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望190点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-05-15 16:05
我跟踪发现文件过64k就不能成功
我用64k文件加1个字节就不能成功写了
还发现psd文件怎么也写不成功

想问问大牛们psd文件和txt文件本质有什么不同
hongpengtao
驱动小牛
驱动小牛
  • 注册日期2006-03-16
  • 最后登录2015-06-03
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望190点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-05-15 16:22
我又发现  els文件是每次都能成功
      txt文件小于64k
                        psd文件什么大小都不行
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
5楼#
发布于:2007-05-15 22:03
Quoted from IFS document:
"Callers of ZwWriteFile must be running at IRQL = PASSIVE_LEVEL and with APCs enabled."

MJ_CLOSE may be called at APC level where it cannot meet the above requirement.
hongpengtao
驱动小牛
驱动小牛
  • 注册日期2006-03-16
  • 最后登录2015-06-03
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望190点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-05-16 09:14
那是不是通过直接发IRP来处理就不会有这些问题呢?
希望devia 和michaelgz 回答
谢谢
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-05-16 09:42
cleanup后只能对文件进行paging read/write,所以自己构造irp需要注意这一点。
hongpengtao
驱动小牛
驱动小牛
  • 注册日期2006-03-16
  • 最后登录2015-06-03
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望190点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-05-16 10:41
谢谢tooflat回答
我也不想自己构造irp因为这样比较烦
加上自己水平有限不到没办法真的不想去用

这里还是想问问
我上面写的代码为什么会c0000002STATUS_NOT_IMPLEMENTED

对于是michaelgz 所说的"MJ_CLOSE may be called at APC level where it cannot meet the above requirement"
我对APC不是非常了解我现在正在查有关文件
但我认为关系不大
因为 ZwWriteFile是否成功我文件类型关系很大
doc els比较大的都没问题
txt在64k中比较敏感
psd就没有成功过

在这里谢谢大家的关注
为了将加密标识加上去我还在努力
希望得到更多的帮助
killvxk
论坛版主
论坛版主
  • 注册日期2005-10-03
  • 最后登录2014-04-14
  • 粉丝3
  • 关注1
  • 积分1082分
  • 威望2003点
  • 贡献值0点
  • 好评度1693点
  • 原创分2分
  • 专家分0分
9楼#
发布于:2007-05-16 11:56
自己发IRP这个最好~
没有战争就没有进步 X3工作组 为您提供最好的军火
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
10楼#
发布于:2007-06-12 17:26
NTSTATUS OSR_FILTER_API OsrFilterForwardCreateIrp(OUT PHANDLE  FileHandle,
    IN ACCESS_MASK  DesiredAccess,IN POBJECT_ATTRIBUTES  ObjectAttributes,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,IN PLARGE_INTEGER  AllocationSize OPTIONAL,
    IN ULONG  FileAttributes,IN ULONG  ShareAccess,IN ULONG  Disposition,IN ULONG  CreateOptions,
    IN PVOID  EaBuffer OPTIONAL,IN ULONG  EaLength,
    IN CREATE_FILE_TYPE  CreateFileType,IN PVOID  ExtraCreateParameters OPTIONAL,
    IN ULONG  Options,IN PVOID  DeviceObject)
{
    NTSTATUS    status;
#ifdef NT_XP

    status = IoCreateFileSpecifyDeviceObjectHint(FileHandle,
                                DesiredAccess,ObjectAttributes,
                                IoStatusBlock,AllocationSize,
                                FileAttributes,ShareAccess,Disposition,CreateOptions,
                                EaBuffer,EaLength,
                                CreateFileType,ExtraCreateParameters,
                                Options,DeviceObject);

#else  // NT_XP
    UNICODE_STRING          QQString = {sizeof(L"??")-sizeof(WCHAR),sizeof(L"??"),L"??"};
    UNICODE_STRING          DosDevString = {sizeof(L"DosDevices")-sizeof(WCHAR),sizeof(L"DosDevices"),L"DosDevices"};
    UNICODE_STRING          GlobalString = {sizeof(L"GLOBAL??")-sizeof(WCHAR),sizeof(L"GLOBAL??"),L"GLOBAL??"};

    //
    // Well, the bad news is that this is not WXP or later so we have to implement the
    // functionality of IoCreateFileSpecifyDeviceObjectHint ourselves.   This entails
    // parsing the input name into a name we can handle and then passing it to the
    // shadow device object that we created earlier which will forward the Irp to
    // a FS or Filter below us..
    //
    if(DeviceObject) {

        UNICODE_STRING      newFileName;
        UNICODE_STRING      parsedFileName = {0,0,NULL};
        OBJECT_ATTRIBUTES   newObjectAttributes;
        ULONG               sizeNeeded = ObjectAttributes->ObjectName->Length +
                                (sizeof(DeviceObject) * (2 * sizeof(WCHAR)));
        UNICODE_STRING      objectName;

        objectName = *ObjectAttributes->ObjectName;

        //
        // Parse the input name.
        //
        status = ParseInputName((PDEVICE_OBJECT) DeviceObject,&objectName);

        if(!NT_SUCCESS(status)) {
            //
            // An error occurred, tell the caller.
            //
            return status;
        }

        //
        // Determine how much memory we need for the name to be built.
        //
        sizeNeeded += sizeof(L"\\Device\\\\") + sizeof(WCHAR);  // \Device\xxxxxxxx\.......

        newFileName.Buffer = (PWSTR) ExAllocatePool(PagedPool,sizeNeeded);

        if(!newFileName.Buffer) {
            //
            // No memory allocated, return the error.
            //
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        //
        // Initialize the buffer to hold the name.
        //
        RtlZeroMemory(newFileName.Buffer,sizeNeeded);

        //
        // Build the appropriate name for the create, so that it goes to our
        // shadow device object....
        //

#if !defined(_WIN64)
        swprintf(newFileName.Buffer,L"\\Device\\%08.8X",(ULONG_PTR) DeviceObject);
#else  // !defined(_WIN64)
        swprintf(newFileName.Buffer,L"\\Device\\%016.16X",(ULONG_PTR) DeviceObject);
#endif // !defined(_WIN64)

        wcsncat(newFileName.Buffer,objectName.Buffer,(objectName.Length)/sizeof(WCHAR));
        newFileName.Length = (USHORT) wcslen(newFileName.Buffer)*sizeof(WCHAR);
        newFileName.MaximumLength = (USHORT) sizeNeeded;
        memcpy(&newObjectAttributes,ObjectAttributes,sizeof(OBJECT_ATTRIBUTES));
        newObjectAttributes.ObjectName = &newFileName;

#if DBG_NAME
        DbgPrint("OsrFilterForwardCreateIrp Create: File Name %wZ\n",&newFileName);
#endif

        //
        // Perform the Create to the Shadow Object.
        //
        status = ZwCreateFile(FileHandle,DesiredAccess,&newObjectAttributes,IoStatusBlock,
                            AllocationSize,FileAttributes,ShareAccess,Disposition,
                            CreateOptions,EaBuffer,EaLength);

        //
        // Clean up the allocated memory...
        //
        ExFreePool(newFileName.Buffer);
        ExFreePool(objectName.Buffer);

    } else {

        //
        // No Hint specified, just do a normal create which will go to the top
        // of the stack....
        //
        status = ZwCreateFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,
                            AllocationSize,FileAttributes,ShareAccess,Disposition,
                            CreateOptions,EaBuffer,EaLength);

    }

#endif // NT_XP
    return status;

}



//
// ParsePath
//
//  This routine is an internal routine called to parse the input
//  file path into its constituent parts...
//
// Inputs:
//  PComponentHead - address of a ListHead which will receive the linked
//                   list of PATH_ENTRY structures containing the parts
//                   of the input name.
//  PPath - Path Name to parse.
//
// Outputs:
//  None.
//
// Returns:
//  STATUS_SUCCESS if the name is parsed successfully, an error otherwise.
//
// Notes:
//  This is only supported in W2K or later.
//

NTSTATUS ParsePath(PLIST_ENTRY PComponentHead, PUNICODE_STRING PPath)
{
    PATH_ENTRY      *pe;
    NTSTATUS        status = STATUS_INSUFFICIENT_RESOURCES;
    UNICODE_STRING  nextComponent;
    PUNICODE_STRING pNextComponent;
    UNICODE_STRING  remainingName;
    BOOLEAN         bFirstPass = TRUE;

    remainingName = *PPath;

    //
    // Loop through a name parsing it into its path pieces.  We do this
    // using FsRtlDissectName.
    //
    while (remainingName.Length > 0) {

        pNextComponent = &nextComponent;

        FsRtlDissectName(remainingName, &nextComponent, &remainingName);

        //
        // Allocate a PATH_ENTRY structure to hold the dissected part of
        // the name.
        //
        pe = (PPATH_ENTRY) ExAllocatePoolWithTag(PagedPool,sizeof(PATH_ENTRY),'2RSO');

        ULONG size = nextComponent.Length+sizeof(WCHAR);

        //
        // See if the memory was allocated.  If not, cleanup after ourselves.
        //
        if(!pe) {
            EmptyPathList(PComponentHead);
            return status;
        }

        //
        // Got the memory, initialize it.
        //
        RtlZeroMemory(pe,sizeof(PATH_ENTRY));

        //
        // see if this is the first pass through the list.  If it is, see if
        // the name is preceeded by \?? or by \DosDevices.  If it is,
        // we substitue \global??
        //

        if(bFirstPass) {

#ifdef NT_XP
            if(RtlCompareUnicodeString(&QQString,&nextComponent,FALSE) == 0) {

                pNextComponent = &GlobalString;
#else // NT_XP
            if(RtlCompareUnicodeString(&GlobalString,&nextComponent,FALSE) == 0) {

                pNextComponent = &QQString;
#endif // NT_XP

            } else if(RtlCompareUnicodeString(&DosDevString,&nextComponent,FALSE) == 0) {

#ifdef NT_XP
                pNextComponent = &GlobalString;
#else // NT_XP
                pNextComponent = &QQString;
#endif // NT_XP

            }

            bFirstPass = FALSE;
        }

        //
        // Allocate memory for the path.
        //

        pe->Path = (PWCHAR) ExAllocatePoolWithTag(PagedPool,pNextComponent->MaximumLength+sizeof(WCHAR),'3RSO');
        if(!pe->Path) {

            //
            // We failed to allocate memory, cleanup and exit.
            //
            ExFreePool(pe);
            EmptyPathList(PComponentHead);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        //
        // Add the part of the parsed name and then continue parsing.
        //

        RtlZeroMemory(pe->Path,pNextComponent->MaximumLength+sizeof(WCHAR));
        wcsncpy(pe->Path,pNextComponent->Buffer,pNextComponent->Length/sizeof(WCHAR));

        InsertTailList(PComponentHead,&pe->ListEntry);

    }

    return STATUS_SUCCESS;
}



//
// EmptyPathList
//
//  This routine is an internal routine called to delete all the
//  entries in a path list.
//
// Inputs:
//  PListHead - address of a ListHead which will receive the linked
//                   list of PATH_ENTRY structures containing the parts
//                   of the input name.
//
// Outputs:
//  None.
//
// Returns:
//  None.
//
// Notes:
//  None.
//
void EmptyPathList(PLIST_ENTRY PListHead)
{
    while(!IsListEmpty(PListHead)) {
        PPATH_ENTRY pe = (PPATH_ENTRY) RemoveHeadList(PListHead);
        ExFreePool(pe->Path);
        ExFreePool(pe);
    }
}

#ifndef NT_XP



//
// AnalyzePath
//
//  This routine is an internal routine called to analyze the input
//  file path in order to determine if there is a DeviceObject that will
//  handle the input name.
//
// Inputs:
//  PHintDeviceObject - address of the device object that must lie in the
//                    path of the device object which handles this name.  
//  PComponentHead - address of a ListHead which contains the linked
//                   list of PATH_ENTRY structures containing the parts
//                   of the input name.
//
// Outputs:
//  PFinalName - address to receive the PFinalName i.e. the part of the
//        name to be passed to the FS for handling.
//
// Returns:
//  STATUS_SUCCESS if the name is parsed successfully, an error otherwise.
//
// Notes:
//  This is only supported in W2K or later.
//

NTSTATUS AnalyzePath(PDEVICE_OBJECT PHintDeviceObject,PLIST_ENTRY PComponentListHead,PWCHAR* PFinalName)
{
    PPATH_ENTRY     ppe = (PPATH_ENTRY) PComponentListHead->Flink;
    PDEVICE_OBJECT  pDeviceObject;
    PFILE_OBJECT    pFileObject;
    ULONG           size = 0;
    ULONG           components = 0;
    PWCHAR          pBuffer = NULL;
    UNICODE_STRING  path = { 0, 0, NULL};
    NTSTATUS        status = STATUS_INSUFFICIENT_RESOURCES;

    *PFinalName = NULL;

    //
    // Figure out the full size of the name that can be built out of the parsed name
    // parts.
    //
    while(TRUE && ((PLIST_ENTRY) ppe != PComponentListHead)) {

        size += wcslen(ppe->Path)*sizeof(WCHAR);
        components++;
        ppe = (PPATH_ENTRY) ppe->ListEntry.Flink;

    }

    //
    // No Size, no problem, just exit with an error.
    //
    if(!size) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    size += ((1 + components) * sizeof(WCHAR));

    //
    // Allocate a name for the string,  if we fail, we
    // exit.
    //
    pBuffer = (PWCHAR) ExAllocatePoolWithTag(PagedPool,size,'4RSO');

    if(!pBuffer) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Initialize the memory and prepare to rebuild the
    // name piece by piece looking for a device that corresponds
    // to the built name.
    //
    RtlZeroMemory(pBuffer,size);

    ppe = (PPATH_ENTRY) PComponentListHead->Flink;

    components = 0;

    while((PLIST_ENTRY) ppe != PComponentListHead) {

        components++;

        //
        // Prefix the name piece being built with a '\'.
        //
        wcscat(pBuffer,L"\\");
        wcscat(pBuffer,ppe->Path);

        //
        // Set up the unicode string which represents the
        // name we will query with.
        //
        path.Length = wcslen(pBuffer)*sizeof(WCHAR);
        path.MaximumLength = path.Length;
        path.Buffer = pBuffer;

        //
        // See if we find a device object which corresponds to the name.
        //
        status = IoGetDeviceObjectPointer(&path,FILE_ANY_ACCESS,&pFileObject,&pDeviceObject);

        //
        // See if we found a match.
        //
        if(NT_SUCCESS(status)) {

            BOOLEAN bFound = FALSE;
            PDEVICE_OBJECT pFsObject = NULL;
            PDEVICE_OBJECT pNextDeviceObject;

            //
            // We have a match, see if we can find the Base File System Device
            // object from the input file object.
            //
            pFsObject = IoGetBaseFileSystemDeviceObject(pFileObject);

            if(!pFsObject) {

                //
                // Well this did not work, so exit with an error.
                //
                ObDereferenceObject(pFileObject);
                ExFreePool(pBuffer);
                return STATUS_OBJECT_NAME_NOT_FOUND;

            }

            //
            // Get the FS Device Object from the VPB in order to start out start our
            // search.
            //
            if(pFsObject->Vpb) {
                pNextDeviceObject = pFsObject->Vpb->DeviceObject;
            } else {
                //
                // There is no VPB.  Let's assume this is a Network device
                // we have been handed.  
                pNextDeviceObject = pFsObject;
            }

            //
            // Okay, I've found a device object.   Let's see if we can find the hint.
            //
            while(pNextDeviceObject) {

                if(pNextDeviceObject == PHintDeviceObject) {
                    bFound = TRUE;
                    break;
                }
                pNextDeviceObject = pNextDeviceObject->AttachedDevice;
            }

            ObDereferenceObject(pFileObject);

            if(!bFound) {

                //
                // Didn't find the hint, so abort the create....
                //
                ExFreePool(pBuffer);
                return STATUS_OBJECT_NAME_NOT_FOUND;

            }

            //
            // We found a handler for the input name and we found
            // the hint device object.   Build the left over parts
            // of the name into the Final Name and return that to
            // to the caller so that the caller can get it passed
            // to the handler for this create call.
            //
            RtlZeroMemory(pBuffer,size);

            wcscat(pBuffer,L"\\");

            ppe = (PPATH_ENTRY) ppe->ListEntry.Flink;

            while(TRUE && ((PLIST_ENTRY) ppe != PComponentListHead)) {
                wcscat(pBuffer,ppe->Path);
                ppe = (PPATH_ENTRY) ppe->ListEntry.Flink;
                if((PLIST_ENTRY) ppe != PComponentListHead) {
                    wcscat(pBuffer,L"\\");
                } else {
                    break;
                }

            }

            //
            // Return the handled name and tell the caller how happy we
            // were to process his function call.
            //
            *PFinalName = pBuffer;
        
            return status;

        }

        //
        // No handler for the name found, continue appending parts of the name.
        //
        ppe = (PPATH_ENTRY) ppe->ListEntry.Flink;

    }

    ExFreePool(pBuffer);

    return status;
}



//
// ParseInputName
//
//  This routine is an internal routine called to Parse the input name.
//
// Inputs:
//  PHintDeviceObject - address of the device object that must lie in the
//                    path of the device object which handles this name.  
//  PPathName - path name to parse.
//
// Outputs:
//  None.
//
// Returns:
//  STATUS_SUCCESS if the name is parsed successfully, an error otherwise.
//
// Notes:
//  This is only supported in W2K or later.
//

NTSTATUS ParseInputName(PDEVICE_OBJECT HintDeviceObject,PUNICODE_STRING PPathName)
{
    PWCHAR      pBuffer = NULL;
    ULONG       tokenCount = 0;
    LIST_ENTRY  ComponentListHead;
    NTSTATUS    status;
    PWCHAR      pFinalName = NULL;

    if(!PPathName) {
        return STATUS_OBJECT_NAME_NOT_FOUND;
    }
        
    if(!PPathName->Buffer) {
        return STATUS_OBJECT_NAME_NOT_FOUND;
    }

    //
    // Initialize the ListHead which will contain the parsed name parts.
    //
    InitializeListHead(&ComponentListHead);

    //
    // Parse the input name into the name parts.
    //
    status = ParsePath(&ComponentListHead,PPathName);

    if(!NT_SUCCESS(status)) {

        ExFreePool(pBuffer);
        return status;

    }

    //
    // Analyze the components of the name....
    //

    status = AnalyzePath(HintDeviceObject,&ComponentListHead,&pFinalName);

    if(NT_SUCCESS(status)) {

        //
        // Set up the new path name we are going to use....
        //

        PPathName->Buffer = pFinalName;
        PPathName->Length = wcslen(pFinalName)*sizeof(WCHAR);
        PPathName->MaximumLength = PPathName->Length;

    }

    //
    // Clean up the components of the name....
    //
    EmptyPathList(&ComponentListHead);

    //
    // Tell them how happy we are.
    //

    return status;
}

NTSTATUS GetFullPathName(PFILE_OBJECT PFileObject,PUNICODE_STRING PNameString)
{
    PFILE_OBJECT relatedFileObject;
    ULONG        pathLen;
    PWCHAR       pathOffset;
    NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;

    PNameString->Length = 0;
    PNameString->MaximumLength = 0;
    PNameString->Buffer = 0;

    //
    // Do this in an exception handling block, in case of mangled names in the
    // file object
    //

    __try {

        //
        // Now, create the full path name. First, calculate the length taking into
        // account space for seperators and the leading drive letter plus ':'
        //

        pathLen = PFileObject->FileName.Length;

        relatedFileObject = PFileObject->RelatedFileObject;
    
        //
        // Only look at related file object if this is a relative name
        //

        if( PFileObject->FileName.Length && PFileObject->FileName.Buffer[0] != L'\\' )  {

            while( relatedFileObject ) {

                pathLen += relatedFileObject->FileName.Length;

                if((relatedFileObject->FileName.Length) &&
                   (relatedFileObject->FileName.Buffer[(relatedFileObject->FileName.Length/sizeof(WCHAR))-1] != L'\\')) {
                    pathLen += sizeof(WCHAR);
                }

                relatedFileObject = relatedFileObject->RelatedFileObject;
            }
    
        }

        PWCHAR pBuffer = (PWCHAR) ExAllocatePoolWithTag(PagedPool,pathLen,'nRSO');

        if(!pBuffer) {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory(pBuffer,pathLen);
        PNameString->Buffer = pBuffer;
        PNameString->MaximumLength = (USHORT) pathLen;
        PNameString->Length = (USHORT) pathLen;

        //
        // If there is no deviceInfo, it means that it is a network drive.
        //

        //sprintf( fullPathName, L"\\." );
    
        //
        // Now, start at the end and work back to the beginning of the path
        //

        pathOffset = (PWCHAR) ((PUCHAR) pBuffer + pathLen - PFileObject->FileName.Length);

        wcsncpy( pathOffset, PFileObject->FileName.Buffer, PFileObject->FileName.Length/sizeof(WCHAR) );

        relatedFileObject = PFileObject->RelatedFileObject;
    
        if( PFileObject->FileName.Buffer[0] != L'\\' )  {

            while( relatedFileObject ) {

                if((relatedFileObject->FileName.Length) &&
                   (relatedFileObject->FileName.Buffer[(relatedFileObject->FileName.Length/sizeof(WCHAR))-1] != L'\\')) {
                    *(pathOffset - 1) = L'\\';
                    pathOffset = (PWCHAR) ((PUCHAR) pathOffset - (relatedFileObject->FileName.Length + sizeof(WCHAR)));
                } else {
                    pathOffset = (PWCHAR) ((PUCHAR) pathOffset - (relatedFileObject->FileName.Length));
                }

                wcsncpy( pathOffset, relatedFileObject->FileName.Buffer,
                        relatedFileObject->FileName.Length/sizeof(WCHAR) );

                relatedFileObject = relatedFileObject->RelatedFileObject;
            }
        }  

        //
        // If we added two '\' to the front because there was a relative file object
        // that specified the root directory, remove one
        //

//        if( pathLen > 3 && fullPathName[2] == '\\' && fullPathName[3] == '\\' )  {
        
//            strcpy( fullPathName + 2, fullPathName + 3 );
//        }

        status = STATUS_SUCCESS;

    } __except( EXCEPTION_EXECUTE_HANDLER ) {

    }

    return status;
}


//
// SendCreateIrpBelowOurFilter
//
//  This routine is an internal routine called to Send the input IRP
//  to the specified device object.
//
// Inputs:
//  DeviceObject - address of the device object that will receive the input
//                 irp.
//  Irp - irp to send
//
// Outputs:
//  None.
//
// Returns:
//  returns whatever IoCallDriver returns.
//
// Notes:
//  This is only supported in XP or later.
//

NTSTATUS SendCreateIrpBelowOurFilter(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
    NTSTATUS                status = STATUS_UNSUCCESSFUL;
    PIO_STACK_LOCATION      currentStackLocation = IoGetCurrentIrpStackLocation(Irp);
    PIO_STACK_LOCATION      nextStackLocation = IoGetNextIrpStackLocation(Irp);
    POSR_FILTER_EXT    shadowExt = (POSR_FILTER_EXT) DeviceObject->DeviceExtension;
    PFILE_OBJECT            pFileObject = currentStackLocation->FileObject;

    (void) GetExtension(DeviceObject, &shadowExt);

    OsrAssert(shadowExt);

    OsrAssert(shadowExt->ShadowedDeviceObject);

    //
    // Set up the Irp to be sent down to the filtered Device Object....
    //

    IoCopyCurrentIrpStackLocationToNext(Irp);

    nextStackLocation->DeviceObject = shadowExt->FilteredDeviceObject;

    //
    // Send it below.....
    //

    status = IoCallDriver(shadowExt->FilteredDeviceObject,Irp);

    //
    // Release the extension
    //

    DereferenceExtension(shadowExt, __LINE__);

    return status;
}
#endif // NT_XP
bluacat
驱动小牛
驱动小牛
  • 注册日期2004-09-13
  • 最后登录2016-09-25
  • 粉丝0
  • 关注0
  • 积分1023分
  • 威望277点
  • 贡献值0点
  • 好评度146点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2007-06-13 18:20
IoCreateFileSpecifyDeviceObjectHint得到的handle除了ZwClose以外其他的Zw×××是不能使用这个handle的。你需要自己构建IRP去读写的
hua1998
驱动牛犊
驱动牛犊
  • 注册日期2006-04-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分175分
  • 威望59点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-06-15 17:42
我在IRP_MJ_CLEANUP中构造IRP也会出现像你这样的问题,返回0xC0000002,只有在flag设为IRP_NOCACHE才会出现,当设为0时就会成功!!
游客

返回顶部