![]() |
ZenWINX Architecture - Reference Manual - Guides |
|
00001 /* 00002 * ZenWINX - WIndows Native eXtended library. 00003 * Copyright (c) 2007-2010 by Dmitri Arkhangelski (dmitriar@gmail.com). 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00027 #include "ntndk.h" 00028 #include "zenwinx.h" 00029 00034 WINX_FILE * __stdcall winx_fopen(const char *filename,const char *mode) 00035 { 00036 ANSI_STRING as; 00037 UNICODE_STRING us; 00038 NTSTATUS status; 00039 HANDLE hFile; 00040 OBJECT_ATTRIBUTES oa; 00041 IO_STATUS_BLOCK iosb; 00042 ACCESS_MASK access_mask = FILE_GENERIC_READ; 00043 ULONG disposition = FILE_OPEN; 00044 WINX_FILE *f; 00045 00046 DbgCheck2(filename,mode,"winx_fopen",NULL); 00047 00048 RtlInitAnsiString(&as,filename); 00049 if(RtlAnsiStringToUnicodeString(&us,&as,TRUE) != STATUS_SUCCESS){ 00050 DebugPrint("Cannot open %s! Not enough memory!",filename); 00051 return NULL; 00052 } 00053 InitializeObjectAttributes(&oa,&us,OBJ_CASE_INSENSITIVE,NULL,NULL); 00054 00055 if(!strcmp(mode,"r")){ 00056 access_mask = FILE_GENERIC_READ; 00057 disposition = FILE_OPEN; 00058 } else if(!strcmp(mode,"w")){ 00059 access_mask = FILE_GENERIC_WRITE; 00060 disposition = FILE_OVERWRITE_IF; 00061 } else if(!strcmp(mode,"r+")){ 00062 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE; 00063 disposition = FILE_OPEN; 00064 } else if(!strcmp(mode,"w+")){ 00065 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE; 00066 disposition = FILE_OVERWRITE_IF; 00067 } else if(!strcmp(mode,"a")){ 00068 access_mask = FILE_APPEND_DATA; 00069 disposition = FILE_OPEN_IF; 00070 } else if(!strcmp(mode,"a+")){ 00071 access_mask = FILE_GENERIC_READ | FILE_APPEND_DATA; 00072 disposition = FILE_OPEN_IF; 00073 } 00074 access_mask |= SYNCHRONIZE; 00075 00076 status = NtCreateFile(&hFile, 00077 access_mask, 00078 &oa, 00079 &iosb, 00080 NULL, 00081 FILE_ATTRIBUTE_NORMAL, 00082 FILE_SHARE_READ | FILE_SHARE_WRITE, 00083 disposition, 00084 FILE_SYNCHRONOUS_IO_NONALERT, 00085 NULL, 00086 0 00087 ); 00088 RtlFreeUnicodeString(&us); 00089 if(status != STATUS_SUCCESS){ 00090 DebugPrintEx(status,"Cannot open %s",filename); 00091 return NULL; 00092 } 00093 f = (WINX_FILE *)winx_heap_alloc(sizeof(WINX_FILE)); 00094 if(!f){ 00095 NtClose(hFile); 00096 DebugPrint("Cannot open %s! Not enough memory!",filename); 00097 return NULL; 00098 } 00099 f->hFile = hFile; 00100 f->roffset.QuadPart = 0; 00101 f->woffset.QuadPart = 0; 00102 return f; 00103 } 00104 00108 size_t __stdcall winx_fread(void *buffer,size_t size,size_t count,WINX_FILE *f) 00109 { 00110 NTSTATUS status; 00111 IO_STATUS_BLOCK iosb; 00112 00113 DbgCheck2(buffer,f,"winx_fread",0); 00114 00115 status = NtReadFile(f->hFile,NULL,NULL,NULL,&iosb, 00116 buffer,size * count,&f->roffset,NULL); 00117 if(NT_SUCCESS(status)){ 00118 status = NtWaitForSingleObject(f->hFile,FALSE,NULL); 00119 if(NT_SUCCESS(status)) status = iosb.Status; 00120 } 00121 if(status != STATUS_SUCCESS){ 00122 DebugPrintEx(status,"Cannot read from a file"); 00123 return 0; 00124 } 00125 if(iosb.Information == 0){ /* encountered on x64 XP */ 00126 f->roffset.QuadPart += size * count; 00127 return count; 00128 } 00129 f->roffset.QuadPart += iosb.Information; 00130 return (iosb.Information / size); 00131 } 00132 00136 size_t __stdcall winx_fwrite(const void *buffer,size_t size,size_t count,WINX_FILE *f) 00137 { 00138 NTSTATUS status; 00139 IO_STATUS_BLOCK iosb; 00140 00141 DbgCheck2(buffer,f,"winx_fwrite",0); 00142 00143 status = NtWriteFile(f->hFile,NULL,NULL,NULL,&iosb, 00144 (void *)buffer,size * count,&f->woffset,NULL); 00145 if(NT_SUCCESS(status)){ 00146 status = NtWaitForSingleObject(f->hFile,FALSE,NULL); 00147 if(NT_SUCCESS(status)) status = iosb.Status; 00148 } 00149 if(status != STATUS_SUCCESS){ 00150 DebugPrintEx(status,"Cannot write to a file"); 00151 return 0; 00152 } 00153 if(iosb.Information == 0){ /* encountered on x64 XP */ 00154 f->woffset.QuadPart += size * count; 00155 return count; 00156 } 00157 f->woffset.QuadPart += iosb.Information; 00158 return (iosb.Information / size); 00159 } 00160 00176 int __stdcall winx_ioctl(WINX_FILE *f, 00177 int code,char *description, 00178 void *in_buffer,int in_size, 00179 void *out_buffer,int out_size, 00180 int *pbytes_returned) 00181 { 00182 IO_STATUS_BLOCK iosb; 00183 NTSTATUS Status; 00184 00185 DbgCheck1(f,"winx_ioctl",-1); 00186 00187 if(out_buffer) RtlZeroMemory(out_buffer,out_size); 00188 00189 if(pbytes_returned) *pbytes_returned = 0; 00190 if((code >> 16) == FILE_DEVICE_FILE_SYSTEM){ /* on x64? */ 00191 Status = NtFsControlFile(f->hFile,NULL,NULL,NULL, 00192 &iosb,code,in_buffer,in_size,out_buffer,out_size); 00193 } else { 00194 Status = NtDeviceIoControlFile(f->hFile,NULL,NULL,NULL, 00195 &iosb,code,in_buffer,in_size,out_buffer,out_size); 00196 } 00197 if(NT_SUCCESS(Status)){ 00198 Status = NtWaitForSingleObject(f->hFile,FALSE,NULL); 00199 if(NT_SUCCESS(Status)) Status = iosb.Status; 00200 } 00201 if(!NT_SUCCESS(Status)/* || Status == STATUS_PENDING*/){ 00202 if(description) 00203 DebugPrintEx(Status,"%s failed",description); 00204 else 00205 DebugPrintEx(Status,"Ioctl %u failed",code); 00206 return (-1); 00207 } 00208 if(pbytes_returned) *pbytes_returned = iosb.Information; 00209 return 0; 00210 } 00211 00216 int __stdcall winx_fflush(WINX_FILE *f) 00217 { 00218 NTSTATUS Status; 00219 IO_STATUS_BLOCK iosb; 00220 00221 DbgCheck1(f,"winx_fflush",-1); 00222 00223 Status = NtFlushBuffersFile(f->hFile,&iosb); 00224 if(!NT_SUCCESS(Status)){ 00225 DebugPrintEx(Status,"NtFlushBuffersFile() failed"); 00226 return (-1); 00227 } 00228 return 0; 00229 } 00230 00234 void __stdcall winx_fclose(WINX_FILE *f) 00235 { 00236 if(!f) return; 00237 if(f->hFile) NtClose(f->hFile); 00238 winx_heap_free(f); 00239 } 00240 00248 int __stdcall winx_create_directory(const char *path) 00249 { 00250 ANSI_STRING as; 00251 UNICODE_STRING us; 00252 NTSTATUS status; 00253 HANDLE hFile; 00254 OBJECT_ATTRIBUTES oa; 00255 IO_STATUS_BLOCK iosb; 00256 00257 DbgCheck1(path,"winx_create_directory",-1); 00258 00259 RtlInitAnsiString(&as,path); 00260 if(RtlAnsiStringToUnicodeString(&us,&as,TRUE) != STATUS_SUCCESS){ 00261 DebugPrint("Cannot create %s! Not enough memory!",path); 00262 return (-1); 00263 } 00264 InitializeObjectAttributes(&oa,&us,OBJ_CASE_INSENSITIVE,NULL,NULL); 00265 00266 status = NtCreateFile(&hFile, 00267 FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_OPEN_FOR_BACKUP_INTENT, 00268 &oa, 00269 &iosb, 00270 NULL, 00271 FILE_ATTRIBUTE_NORMAL, 00272 FILE_SHARE_READ | FILE_SHARE_WRITE, 00273 FILE_CREATE, 00274 FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, 00275 NULL, 00276 0 00277 ); 00278 RtlFreeUnicodeString(&us); 00279 if(NT_SUCCESS(status)){ 00280 NtClose(hFile); 00281 return 0; 00282 } 00283 /* if it already exists then return success */ 00284 if(status == STATUS_OBJECT_NAME_COLLISION) return 0; 00285 DebugPrintEx(status,"Cannot create %s",path); 00286 return (-1); 00287 } 00288 00294 int __stdcall winx_delete_file(const char *filename) 00295 { 00296 ANSI_STRING as; 00297 UNICODE_STRING us; 00298 NTSTATUS status; 00299 OBJECT_ATTRIBUTES oa; 00300 00301 DbgCheck1(filename,"winx_delete_file",-1); 00302 00303 RtlInitAnsiString(&as,filename); 00304 if(RtlAnsiStringToUnicodeString(&us,&as,TRUE) != STATUS_SUCCESS){ 00305 DebugPrint("Cannot delete %s! Not enough memory!",filename); 00306 return (-1); 00307 } 00308 00309 InitializeObjectAttributes(&oa,&us,OBJ_CASE_INSENSITIVE,NULL,NULL); 00310 status = NtDeleteFile(&oa); 00311 RtlFreeUnicodeString(&us); 00312 if(!NT_SUCCESS(status)){ 00313 DebugPrintEx(status,"Cannot delete %s",filename); 00314 return (-1); 00315 } 00316 return 0; 00317 } 00318