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驱动