aurain
技术文摘
posts - 137,  comments - 268,  trackbacks - 0

IRP中I/O堆栈Parameters.Create参数
在IO_STACK_LOCATION结构体中,Parameters这个union其中有个Create结构体,对应IRP_MJ_CREATE,此IRP的分发函数处理应用层的CreateFile函数,
CreateFile函数进入内核后是调用NtCreateFile,NtCreateFile的声明同ZwCreatFile
在ZwCreateFile中设置的一些参数,在Parameters.Create中可以获取到。
下面先看CreateFile及ZwCreateFile原型:
HANDLE WINAPI CreateFile(
  __in          LPCTSTR lpFileName,
  __in          DWORD dwDesiredAccess,
  __in          DWORD dwShareMode,
  __in          LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  __in          DWORD dwCreationDisposition,
  __in          DWORD dwFlagsAndAttributes,
  __in          HANDLE hTemplateFile
);

NTSTATUS 
  ZwCreateFile(
    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  CreateDisposition,
    IN ULONG  CreateOptions,
    IN PVOID  EaBuffer  OPTIONAL,
    IN ULONG  EaLength
    );

再看Parameters.Create结构体:
 struct {
            PIO_SECURITY_CONTEXT SecurityContext;
            ULONG Options;
            USHORT POINTER_ALIGNMENT FileAttributes;
            USHORT ShareAccess;
            ULONG POINTER_ALIGNMENT EaLength;
        } Create;

在Parameters.Create的Options域中,高8位对应ZwCreateFile的dwCreationDisposition,低24位对应ZwCreateFile的CreateOptions,
ShareAccess对应ZwCreateFile的ShareAccess,FileAttributes对应ZwCreateFile的FileAttributes,SecurityContext->DesiredAccess对应
ZwCreateFile的DesiredAccess。

CreationDisposition = (Parameters.Create.Options >> 24) & 0x000000ff;
CreateOptions = Parameters.Create.Options & 0x00ffffff;
DesiredAccess = Parameters.Create.SecurityContext->DesiredAccess;
ShareAccess = Parameters.Create.ShareAccess;
FileAttributes = Parameters.Create.FileAttributes;

DesiredAccess----这个参数指定一个访问权限,大概有以下的权限:
FILE_ANY_ACCESS 0x0000 // any type
FILE_READ_ACCESS 0x0001 // file & pipe
FILE_READ_DATA 0x0001 // file & pipe
FILE_LIST_DIRECTORY 0x0001 // directory
FILE_WRITE_ACCESS 0x0002 // file & pipe
FILE_WRITE_DATA 0x0002 // file & pipe
FILE_ADD_FILE 0x0002 // directory
FILE_APPEND_DATA 0x0004 // file
FILE_ADD_SUBDIRECTORY 0x0004 // directory
FILE_CREATE_PIPE_INSTANCE 0x0004 // named pipe
FILE_READ_EA 0x0008 // file & directory
FILE_WRITE_EA 0x0010 // file & directory
FILE_EXECUTE 0x0020 // file
FILE_TRAVERSE 0x0020 // directory
FILE_DELETE_CHILD 0x0040 // directory
FILE_READ_ATTRIBUTES 0x0080 // all types
FILE_WRITE_ATTRIBUTES 0x0100 // all types
FILE_ALL_ACCESS // All of the preceding +
STANDARD_RIGHTS_ALL
最后一个权限最大
这里面要注意的是范围问题,有的值只适合目录,有的只适合管道,有的只适合命名管道,有的同时适用,想下这个地方可以做什么文章

FileAttributes---这个参数指定文件的属性,刚才是文件对象的属性。可以是以下的:
FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_HIDDEN
FILE_ATTRIBUTE_SYSTEM
FILE_ATTRIBUTE_DIRECTORY
FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_TEMPORARY
FILE_ATTRIBUTE_SPARSE_FILE
FILE_ATTRIBUTE_REPARSE_POINT
FILE_ATTRIBUTE_COMPRESSED
FILE_ATTRIBUTE_OFFLINE
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
FILE_ATTRIBUTE_ENCRYPTED

ShareAccess---指定共享的权限,以下三种的组合:
FILE_SHARE_READ
FILE_SHARE_WRITE
FILE_SHARE_DELETE

CreateDisposition---这个参数指定要对文件干嘛,呼呼,可以是下面的值:
FILE_SUPERSEDE
FILE_OPEN
FILE_CREATE
FILE_OPEN_IF
FILE_OVERWRITE
FILE_OVERWRITE_IF


CreateOptions---这个参数指定创建或者打开文件的时候做的一些事情,可以是以下的组合:
FILE_DIRECTORY_FILE
FILE_WRITE_THROUGH
FILE_SEQUENTIAL_ONLY
FILE_NO_INTERMEDIATE_BUFFERING
FILE_SYNCHRONOUS_IO_ALERT
FILE_SYNCHRONOUS_IO_NONALERT
FILE_NON_DIRECTORY_FILE
FILE_CREATE_TREE_CONNECTION
FILE_COMPLETE_IF_OPLOCKED
FILE_NO_EA_KNOWLEDGE
FILE_OPEN_FOR_RECOVERY
FILE_RANDOM_ACCESS
FILE_DELETE_ON_CLOSE
FILE_OPEN_BY_FILE_ID
FILE_OPEN_FOR_BACKUP_INTENT
FILE_NO_COMPRESSION
FILE_RESERVE_OPFILTER
FILE_OPEN_REPARSE_POINT
FILE_OPEN_NO_RECALL
FILE_OPEN_FOR_FREE_SPACE_QUERY

 附:CreateFile实现
HANDLE WINAPI CreateFileW (LPCWSTR          lpFileName,
00092                 DWORD           dwDesiredAccess,
00093                 DWORD           dwShareMode,
00094                 LPSECURITY_ATTRIBUTES   lpSecurityAttributes,
00095                 DWORD           dwCreationDisposition,
00096                 DWORD           dwFlagsAndAttributes,
00097                 HANDLE          hTemplateFile)
00098 {
00099    OBJECT_ATTRIBUTES ObjectAttributes;
00100    IO_STATUS_BLOCK IoStatusBlock;
00101    UNICODE_STRING NtPathU;
00102    HANDLE FileHandle;
00103    NTSTATUS Status;
00104    ULONG FileAttributes, Flags = 0;
00105    PVOID EaBuffer = NULL;
00106    ULONG EaLength = 0;
00107
00108    if (!lpFileName || !lpFileName[0])
00109    {
00110        SetLastError( ERROR_PATH_NOT_FOUND );
00111        return INVALID_HANDLE_VALUE;
00112    }
00113
00114    TRACE("CreateFileW(lpFileName %S)\n",lpFileName);
00115
00116    /* validate & translate the creation disposition */
00117    switch (dwCreationDisposition)
00118      {
00119       case CREATE_NEW:
00120     dwCreationDisposition = FILE_CREATE;
00121     break;
00122
00123       case CREATE_ALWAYS:
00124     dwCreationDisposition = FILE_OVERWRITE_IF;
00125     break;
00126
00127       case OPEN_EXISTING:
00128     dwCreationDisposition = FILE_OPEN;
00129     break;
00130
00131       case OPEN_ALWAYS:
00132     dwCreationDisposition = FILE_OPEN_IF;
00133     break;
00134
00135       case TRUNCATE_EXISTING:
00136     dwCreationDisposition = FILE_OVERWRITE;
00137         break;
00138
00139       default:
00140         SetLastError(ERROR_INVALID_PARAMETER);
00141         return (INVALID_HANDLE_VALUE);
00142      }
00143
00144    /* check for console input/output */
00145    if (0 == _wcsicmp(L"CONOUT$", lpFileName)
00146        || 0 == _wcsicmp(L"CONIN$", lpFileName))
00147    {
00148       return OpenConsoleW(lpFileName,
00149                           dwDesiredAccess,
00150                           lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE,
00151                           FILE_SHARE_READ | FILE_SHARE_WRITE);
00152    }
00153
00154   /* validate & translate the flags */
00155
00156    /* translate the flags that need no validation */
00157    if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
00158    {
00159       /* yes, nonalert is correct! apc's are not delivered
00160       while waiting for file io to complete */
00161       Flags |= FILE_SYNCHRONOUS_IO_NONALERT;
00162    }
00163
00164    if(dwFlagsAndAttributes & FILE_FLAG_WRITE_THROUGH)
00165       Flags |= FILE_WRITE_THROUGH;
00166
00167    if(dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
00168       Flags |= FILE_NO_INTERMEDIATE_BUFFERING;
00169
00170    if(dwFlagsAndAttributes & FILE_FLAG_RANDOM_ACCESS)
00171       Flags |= FILE_RANDOM_ACCESS;
00172
00173    if(dwFlagsAndAttributes & FILE_FLAG_SEQUENTIAL_SCAN)
00174       Flags |= FILE_SEQUENTIAL_ONLY;
00175
00176    if(dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE)
00177       Flags |= FILE_DELETE_ON_CLOSE;
00178
00179    if(dwFlagsAndAttributes & FILE_FLAG_BACKUP_SEMANTICS)
00180    {
00181       if(dwDesiredAccess & GENERIC_ALL)
00182          Flags |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REMOTE_INSTANCE;
00183       else
00184       {
00185          if(dwDesiredAccess & GENERIC_READ)
00186             Flags |= FILE_OPEN_FOR_BACKUP_INTENT;
00187
00188          if(dwDesiredAccess & GENERIC_WRITE)
00189             Flags |= FILE_OPEN_REMOTE_INSTANCE;
00190       }
00191    }
00192    else
00193       Flags |= FILE_NON_DIRECTORY_FILE;
00194
00195    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_REPARSE_POINT)
00196       Flags |= FILE_OPEN_REPARSE_POINT;
00197
00198    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_NO_RECALL)
00199       Flags |= FILE_OPEN_NO_RECALL;
00200
00201    FileAttributes = (dwFlagsAndAttributes & (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY));
00202
00203    /* handle may allways be waited on and querying attributes are allways allowed */
00204    dwDesiredAccess |= SYNCHRONIZE | FILE_READ_ATTRIBUTES;
00205
00206    /* FILE_FLAG_POSIX_SEMANTICS is handled later */
00207
00208    /* validate & translate the filename */
00209    if (!RtlDosPathNameToNtPathName_U (lpFileName,
00210                       &NtPathU,
00211                       NULL,
00212                       NULL))
00213    {
00214      WARN("Invalid path\n");
00215      SetLastError(ERROR_FILE_NOT_FOUND);
00216      return INVALID_HANDLE_VALUE;
00217    }
00218
00219    TRACE("NtPathU \'%wZ\'\n", &NtPathU);
00220
00221    if (hTemplateFile != NULL)
00222    {
00223       FILE_EA_INFORMATION EaInformation;
00224
00225       for (;;)
00226       {
00227          /* try to get the size of the extended attributes, if we fail just continue
00228             creating the file without copying the attributes! */
00229          Status = NtQueryInformationFile(hTemplateFile,
00230                                          &IoStatusBlock,
00231                                          &EaInformation,
00232                                          sizeof(FILE_EA_INFORMATION),
00233                                          FileEaInformation);
00234          if (NT_SUCCESS(Status) && (EaInformation.EaSize != 0))
00235          {
00236             /* there's extended attributes to read, let's give it a try */
00237             EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
00238                                        0,
00239                                        EaInformation.EaSize);
00240             if (EaBuffer == NULL)
00241             {
00242                RtlFreeHeap(RtlGetProcessHeap(),
00243                            0,
00244                            NtPathU.Buffer);
00245
00246                /* the template file handle is valid and has extended attributes,
00247                   however we seem to lack some memory here. We should fail here! */
00248                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00249                return INVALID_HANDLE_VALUE;
00250             }
00251
00252             Status = NtQueryEaFile(hTemplateFile,
00253                                    &IoStatusBlock,
00254                                    EaBuffer,
00255                                    EaInformation.EaSize,
00256                                    FALSE,
00257                                    NULL,
00258                                    0,
00259                                    NULL,
00260                                    TRUE);
00261
00262             if (NT_SUCCESS(Status))
00263             {
00264                /* we successfully read the extended attributes, break the loop
00265                   and continue */
00266                EaLength = EaInformation.EaSize;
00267                break;
00268             }
00269             else
00270             {
00271                RtlFreeHeap(RtlGetProcessHeap(),
00272                            0,
00273                            EaBuffer);
00274                EaBuffer = NULL;
00275
00276                if (Status != STATUS_BUFFER_TOO_SMALL)
00277                {
00278                   /* unless we just allocated not enough memory, break the loop
00279                      and just continue without copying extended attributes */
00280                   break;
00281                }
00282             }
00283          }
00284          else
00285          {
00286             /* we either failed to get the size of the extended attributes or
00287                they're empty, just continue as there's no need to copy
00288                attributes */
00289             break;
00290          }
00291       }
00292    }
00293
00294    /* build the object attributes */
00295    InitializeObjectAttributes(&ObjectAttributes,
00296                               &NtPathU,
00297                               0,
00298                               NULL,
00299                               NULL);
00300
00301    if (lpSecurityAttributes)
00302    {
00303       if(lpSecurityAttributes->bInheritHandle)
00304          ObjectAttributes.Attributes |= OBJ_INHERIT;
00305
00306       ObjectAttributes.SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
00307    }
00308
00309    if(!(dwFlagsAndAttributes & FILE_FLAG_POSIX_SEMANTICS))
00310     ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00311
00312    /* perform the call */
00313    Status = NtCreateFile (&FileHandle,
00314               dwDesiredAccess,
00315               &ObjectAttributes,
00316               &IoStatusBlock,
00317               NULL,
00318               FileAttributes,
00319               dwShareMode,
00320               dwCreationDisposition,
00321               Flags,
00322               EaBuffer,
00323               EaLength);
00324
00325    RtlFreeHeap(RtlGetProcessHeap(),
00326                0,
00327                NtPathU.Buffer);
00328
00329    /* free the extended attributes buffer if allocated */
00330    if (EaBuffer != NULL)
00331    {
00332       RtlFreeHeap(RtlGetProcessHeap(),
00333                   0,
00334                   EaBuffer);
00335    }
00336
00337    /* error */
00338    if (!NT_SUCCESS(Status))
00339    {
00340       /* In the case file creation was rejected due to CREATE_NEW flag
00341        * was specified and file with that name already exists, correct
00342        * last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
00343        * Note: RtlNtStatusToDosError is not the subject to blame here.
00344        */
00345       if (Status == STATUS_OBJECT_NAME_COLLISION &&
00346           dwCreationDisposition == FILE_CREATE)
00347       {
00348          SetLastError( ERROR_FILE_EXISTS );
00349       }
00350       else
00351       {
00352          BaseSetLastNTError (Status);
00353       }
00354
00355       return INVALID_HANDLE_VALUE;
00356    }
00357
00358   /*
00359   create with OPEN_ALWAYS (FILE_OPEN_IF) returns info = FILE_OPENED or FILE_CREATED
00360   create with CREATE_ALWAYS (FILE_OVERWRITE_IF) returns info = FILE_OVERWRITTEN or FILE_CREATED
00361   */
00362   if (dwCreationDisposition == FILE_OPEN_IF)
00363   {
00364     SetLastError(IoStatusBlock.Information == FILE_OPENED ? ERROR_ALREADY_EXISTS : 0);
00365   }
00366   else if (dwCreationDisposition == FILE_OVERWRITE_IF)
00367   {
00368     SetLastError(IoStatusBlock.Information == FILE_OVERWRITTEN ? ERROR_ALREADY_EXISTS : 0);
00369   }
00370
00371   return FileHandle;
00372 }

posted on 2011-09-01 15:27 阅读(3625) 评论(0)  编辑 收藏 引用 所属分类: windows驱动

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用链接

留言簿(17)

随笔分类(138)

随笔档案(137)

网络开发

最新随笔

搜索

  •  

积分与排名

  • 积分 - 493568
  • 排名 - 36

最新随笔

最新评论

阅读排行榜

评论排行榜