00001
00010 #include "dkcGenericFileSystem.h"
00011
00012
00013
00014
00015
00016 #ifdef WIN32
00017 #include <io.h>
00018 #include <fcntl.h>
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <errno.h>
00022 #ifdef _MSC_VER
00023
00024 # pragma warning(disable:4055 4152)
00025 #endif
00026
00027
00028
00029
00030 enum{
00031 edkcWin32SJIS = 0,
00032 edkcWin32Unicode = 1,
00033 };
00034
00035
00036 typedef HANDLE (WINAPI *CreateFileA_FT)(
00037 LPCSTR lpFileName,
00038 DWORD dwDesiredAccess,
00039 DWORD dwShareMode,
00040 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
00041 DWORD dwCreationDisposition,
00042 DWORD dwFlagsAndAttributes,
00043 HANDLE hTemplateFile
00044 );
00045
00046
00047 typedef HANDLE (WINAPI *CreateFileW_FT)(
00048 LPCWSTR lpFileName,
00049 DWORD dwDesiredAccess,
00050 DWORD dwShareMode,
00051 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
00052 DWORD dwCreationDisposition,
00053 DWORD dwFlagsAndAttributes,
00054 HANDLE hTemplateFile
00055 );
00056
00057
00058 typedef BOOL (WINAPI *SetFileAttributesA_FT)(
00059 LPCSTR lpFileName,
00060 DWORD dwFileAttributes
00061 );
00062
00063
00064 typedef BOOL (WINAPI *SetFileAttributesW_FT)(
00065 LPCWSTR lpFileName,
00066 DWORD dwFileAttributes
00067 );
00068
00069
00070
00071 typedef DWORD (WINAPI *GetFileAttributesA_FT)(
00072 LPCSTR lpFileName
00073 );
00074
00075 typedef DWORD (WINAPI *GetFileAttributesW_FT)(
00076 LPCWSTR lpFileName
00077 );
00078
00079
00080 typedef BOOL (WINAPI *DeleteFileA_FT)(
00081 LPCSTR lpFileName
00082 );
00083
00084 typedef BOOL (WINAPI *DeleteFileW_FT)(
00085 LPCWSTR lpFileName
00086 );
00087
00088
00089
00090
00091 DKC_INLINE void dkc_to_CreateFile_arg_data(DKC_OPEN_ARG_DATA *data,uint32 flag)
00092 {
00093 BOOL wm = (flag & edkcWriteMode) != 0;
00094 BOOL rm = (flag & edkcReadMode) != 0;
00095 BOOL pm = (flag & edkcPostScriptMode) != 0;
00096 memset(data,0,sizeof(*data));
00097
00098 if(pm){
00099
00100
00101
00102
00103
00104
00105
00106 data->CreationDisposition |= OPEN_EXISTING;
00107 }else{
00108 if(wm && rm){
00109
00110 data->CreationDisposition |= OPEN_EXISTING;
00111 }else if(wm){
00112
00113 data->CreationDisposition |= CREATE_ALWAYS;
00114 }else if(rm){
00115
00116 data->CreationDisposition |= OPEN_EXISTING;
00117 }
00118
00119 }
00120
00121
00122 if(wm){
00123
00124 data->ShareMode |= FILE_SHARE_READ;
00125
00126 data->DesiredAccess |= GENERIC_WRITE;
00127 }
00128 if(rm){
00129
00130 data->ShareMode |= FILE_SHARE_READ;
00131
00132 data->DesiredAccess |= GENERIC_READ;
00133 }
00134
00135
00136
00137
00138 data->FlagsAndAttributes |= FILE_ATTRIBUTE_NORMAL;
00139
00140
00141 }
00142
00143
00144 #define WIN32_FS_CALL(type,obj,function_address)\
00145 (type)(function_address)
00146
00147
00148 static void *win32_open(void *pobj,uint32 flags,const void *filename){
00149 DKC_WIN32_FS *pfs = pobj;
00150 HANDLE fp;
00151 DKC_OPEN_ARG_DATA Arg;
00152 CreateFileA_FT af = pfs->CreateFile;
00153 CreateFileW_FT wf = pfs->CreateFile;
00154
00155
00156 dkc_to_CreateFile_arg_data(&Arg,flags);
00157
00158
00159 if(edkcWin32SJIS == pfs->mFlag){
00160 fp = af(
00161 filename,
00162 Arg.DesiredAccess,
00163 Arg.ShareMode,
00164 Arg.lpSecurityAttributes,
00165 Arg.CreationDisposition,
00166 Arg.FlagsAndAttributes,
00167 Arg.TemplateFile
00168
00169 );
00170 }else{
00171 fp = wf(
00172 filename,
00173 Arg.DesiredAccess,
00174 Arg.ShareMode,
00175 Arg.lpSecurityAttributes,
00176 Arg.CreationDisposition,
00177 Arg.FlagsAndAttributes,
00178 Arg.TemplateFile
00179
00180 );
00181
00182 }
00183
00184 if(fp==INVALID_HANDLE_VALUE){
00185
00186 return NULL;
00187 }
00188 pfs->mHandle = fp;
00189 memcpy(&(pfs->mArg),&Arg,sizeof(pfs->mArg));
00190
00191 return fp;
00192 }
00193
00194
00195 static int win32_read(void *pobj,void *pb,size_t size,size_t *readsize){
00196 DKC_WIN32_FS *pfs = pobj;
00197 HANDLE h = pfs->mHandle;
00198
00199 BOOL r = ReadFile(
00200 h,
00201 pb,
00202 size,
00203 (LPDWORD)&readsize,
00204 NULL
00205 );
00206
00207 if(0==r){
00208 pfs->mLastError = GetLastError();
00209
00210 r = edk_FAILED;
00211 goto End;
00212 }
00213 if (r && readsize== 0)
00214 {
00215
00216 }
00217 r = edk_SUCCEEDED;
00218 End:
00219
00220 return r;
00221 }
00222
00223 static int win32_write(void *pobj,const void *pb,size_t size,size_t *writesize){
00224 DKC_WIN32_FS *pfs = pobj;
00225
00226
00227
00228 BOOL r = WriteFile(pfs->mHandle, pb, size , (LPDWORD)&writesize, NULL);
00229
00230 if(r==FALSE){
00231
00232 pfs->mLastError = GetLastError();
00233 r = edk_FAILED;
00234 goto End;
00235 }
00236 r = edk_SUCCEEDED;
00237 End:
00238
00239 return r;
00240
00241 }
00242 static int win32_close(void *pobj){
00243 DKC_WIN32_FS *pfs = pobj;
00244 int r;
00245 if(pfs->mHandle != INVALID_HANDLE_VALUE)
00246 {
00247 if(FALSE==CloseHandle(pfs->mHandle)){
00248 r = edk_FAILED;
00249 goto End;
00250 }
00251 }
00252 pfs->mHandle = INVALID_HANDLE_VALUE;
00253 r = edk_SUCCEEDED;
00254 End:
00255 return r;
00256 }
00257
00258 static int win32_seek(void *pobj,const DKC_GFS_SEEK_ARG *parg){
00259 DKC_WIN32_FS *pfs = pobj;
00260 DWORD origin = 0xFFFFFFFF;
00261 DWORD dw;
00262 DWORD LastError;
00263 int r;
00264
00265 switch(parg->origin){
00266 case edkcSeekSet:
00267 origin = FILE_BEGIN;
00268 break;
00269 case edkcSeekCurrent:
00270 origin = FILE_CURRENT;
00271 break;
00272 case edkcSeekEnd:
00273 origin = FILE_END;
00274 break;
00275 }
00276 dkcmNOT_ASSERT(0xFFFFFFFF==origin);
00277
00278
00279
00280
00281 dw = SetFilePointer(pfs->mHandle,
00282 parg->Point.u.LowPart,
00283 (PLONG)&(parg->Point.u.HighPart),
00284 origin
00285 );
00286
00287
00288
00289
00290
00291 LastError = GetLastError();
00292 pfs->mLastError = LastError;
00293 if(LastError != NOERROR)
00294 {
00295
00296
00297
00298
00299 r = edk_FAILED;
00300 goto End;
00301 }
00302
00303
00304 r = edk_SUCCEEDED;
00305 End:
00306
00307 return r;
00308 }
00309
00310
00311 static int win32_tell(void *pobj,DKC_UINT64_STRUCT *dest){
00312 DKC_WIN32_FS *pfs = pobj;
00313 LONG high = 0, low = 0;
00314 DKC_UINT64_STRUCT ull;
00315 DWORD LastError;
00316 int r;
00317
00318 low = SetFilePointer(pfs->mHandle,
00319 low,
00320 &high, FILE_CURRENT
00321 );
00322
00323
00324
00325
00326
00327
00328 LastError = GetLastError();
00329 pfs->mLastError = LastError;
00330 if(LastError != NOERROR)
00331 {
00332
00333
00334
00335
00336 r = edk_FAILED;
00337 goto End;
00338 }
00339
00340
00341 r = edk_SUCCEEDED;
00342 ull.u.LowPart = low;
00343 ull.u.HighPart = high;
00344 memcpy(dest,&ull,sizeof(*dest));
00345 End:
00346
00347 return r;
00348
00349 }
00350
00351 static int win32_delete_file(void *pobj,const void *filename_){
00352 DKC_WIN32_FS *pfs = pobj;
00353 BOOL r;
00354 DeleteFileA_FT af = pfs->DeleteFile;
00355 DeleteFileW_FT wf = pfs->DeleteFile;
00356 if(edkcWin32SJIS == pfs->mFlag){
00357 r = af(filename_);
00358 }else{
00359 r = wf(filename_);
00360 }
00361 if(FALSE==r){
00362 return edk_FAILED;
00363 }
00364 return edk_SUCCEEDED;
00365 }
00366
00367
00368
00369
00370 #define LoadFunctionGFS(funcname,dest) \
00371 tp = dkcGetProcAddress(dllp,funcname);\
00372 if(NULL==tp){\
00373 return FALSE;\
00374 }\
00375 dest = tp
00376
00377 static BOOL load_function_win32_sjis(DKC_DLL *dllp,DKC_WIN32_FS *p){
00378 void *tp;
00379 LoadFunctionGFS("CreateFileA",p->CreateFile);
00380 LoadFunctionGFS("SetFileAttributesA",p->SetFileAttributes);
00381 LoadFunctionGFS("GetFileAttributesA",p->GetFileAttributes);
00382 LoadFunctionGFS("DeleteFileA",p->DeleteFile);
00383 p->mFlag = edkcWin32SJIS;
00384 return TRUE;
00385 }
00386
00387 static BOOL load_function_win32_unicode(DKC_DLL *dllp,DKC_WIN32_FS *p){
00388 void *tp;
00389 LoadFunctionGFS("CreateFileW",p->CreateFile);
00390 LoadFunctionGFS("SetFileAttributesW",p->SetFileAttributes);
00391 LoadFunctionGFS("GetFileAttributesW",p->GetFileAttributes);
00392 LoadFunctionGFS("DeleteFileW",p->DeleteFile);
00393 p->mFlag = edkcWin32Unicode;
00394 return TRUE;
00395 }
00396 typedef BOOL (*load_fs_func_win32_t)(DKC_DLL *,DKC_WIN32_FS *);
00397
00398 static DKC_WIN32_FS *alloc_win32_fs(load_fs_func_win32_t ploadfunc){
00399
00400 DKC_WIN32_FS *p;
00401 DKC_DLL *dllp;
00402
00403 p = dkcAllocate(sizeof(DKC_WIN32_FS));
00404 if(NULL==p){
00405 return NULL;
00406 }
00407
00408 dllp = dkcLoadLibrary("kernel32.dll");
00409 if(NULL==dllp){
00410 goto Error;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420 if(FALSE==ploadfunc(dllp,p)){
00421 goto Error;
00422 }
00423
00424 p->mdllobj = dllp;
00425 return p;
00426
00427 Error:
00428 dkcFree(&p);
00429 return NULL;
00430 }
00431
00432
00433
00434 static int free_win32_fs(void *pa){
00435 DKC_WIN32_FS *p = pa;
00436
00437 win32_close(p);
00438
00439 if(DKUTIL_FAILED(dkcUnloadLibrary(&(p->mdllobj))))
00440 {
00441 return edk_FAILED;
00442 }
00443 memset(p,0,sizeof(*p));
00444 return dkcFree(&p);
00445
00446 }
00447
00448 static DKC_GENERIC_FILESYSTEM *WINAPI dkcAlloc_Win32_FileSystem(BOOL isSJIS){
00449 void *fp;
00450
00451 DKC_GENERIC_FILESYSTEM *pfs = dkcAllocate(sizeof(DKC_GENERIC_FILESYSTEM));
00452 if(NULL==pfs){
00453 return NULL;
00454 }
00455
00456 if(isSJIS){
00457 fp = load_function_win32_sjis;
00458 }else{
00459 fp = load_function_win32_unicode;
00460 }
00461
00462 pfs->mfp = alloc_win32_fs(fp);
00463
00464 if(NULL==pfs->mfp){
00465 goto Error;
00466 }
00467 pfs->mfClose = win32_close;
00468 pfs->mfOpen = win32_open;
00469 pfs->mfRead = win32_read;
00470 pfs->mfSeek = win32_seek;
00471 pfs->mfTell = win32_tell;
00472 pfs->mfWrite = win32_write;
00473 pfs->mfDeleteFile = win32_delete_file;
00474
00475 pfs->mfObjFree = free_win32_fs;
00476 return pfs;
00477
00478 Error:
00479
00480 dkcFree(&pfs);
00481 return NULL;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 DKC_GENERIC_FILESYSTEM *WINAPI dkcAlloc_SJIS_FileSystem()
00497 {
00498 return dkcAlloc_Win32_FileSystem(TRUE);
00499 }
00500
00501
00502
00503 DKC_GENERIC_FILESYSTEM *WINAPI dkcAlloc_UNICODE_FileSystem()
00504 {
00505 return dkcAlloc_Win32_FileSystem(FALSE);
00506 }
00507
00508
00509 #endif
00510
00511
00512
00513 int WINAPI dkcFreeGenericFileSystem(DKC_GENERIC_FILESYSTEM **pp){
00514 DKC_GENERIC_FILESYSTEM *p = *pp;
00515 DKC_GFS_FREE_F_TYPE fff;
00516 int r;
00517
00518 if(NULL==pp || NULL==p){
00519 return edk_FAILED;
00520 }
00521
00522
00523 fff = p->mfObjFree;
00524 r = fff(p->mfp);
00525 if(DKUTIL_FAILED(r)){
00526 return edk_FAILED;
00527 }
00528
00529 return dkcFree(pp);
00530 }
00531
00532 int WINAPI dkcGenericFileSystemOpen(DKC_GENERIC_FILESYSTEM *ptr,uint32 flags,const void *filename){
00533 void *p = ptr->mfOpen(ptr->mfp,flags,filename);
00534 if(NULL==p){
00535 return edk_FAILED;
00536 }
00537 return edk_SUCCEEDED;
00538 }
00539
00540 int WINAPI dkcGenericFileSystemClose(DKC_GENERIC_FILESYSTEM *ptr){
00541 return ptr->mfClose(ptr->mfp);
00542 }
00543
00544 int WINAPI dkcGenericFileSystemRead(DKC_GENERIC_FILESYSTEM *ptr,void *pbuff,size_t size,size_t *read_size)
00545 {
00546 return ptr->mfRead(ptr->mfp,pbuff,size,read_size);
00547 }
00548
00549 int WINAPI dkcGenericFileSystemWrite(DKC_GENERIC_FILESYSTEM *ptr,const void *pbuff,size_t size,size_t *write_size)
00550 {
00551 return ptr->mfWrite(ptr->mfp,pbuff,size,write_size);
00552 }
00553
00554 int WINAPI dkcGenericFileSystemSeek(DKC_GENERIC_FILESYSTEM *ptr,const DKC_GFS_SEEK_ARG *parg)
00555 {
00556 return ptr->mfSeek(ptr->mfp,parg);
00557 }
00558
00559 int WINAPI dkcGenericFileSystemTell(DKC_GENERIC_FILESYSTEM *ptr,DKC_UINT64_STRUCT *offset)
00560 {
00561 return ptr->mfTell(ptr->mfp,offset);
00562 }
00563
00564 int WINAPI dkcGenericFileSystemDeleteFile(DKC_GENERIC_FILESYSTEM *ptr,const void *filename)
00565 {
00566 return ptr->mfDeleteFile(ptr->mfp,filename);
00567 }
00568
00569
00570
00571
00572 DKC_FILE64 *WINAPI dkcAllocFile64(uint32 flags,const void *filename)
00573 {
00574 DKC_FILE64 *p = dkcAllocate(sizeof(DKC_FILE64));
00575 if(NULL==p) return NULL;
00576 p->handle = -1;
00577 if(DKUTIL_FAILED(dkcFile64Open(p,flags,filename))){
00578 dkcFreeFile64(&p);
00579 return NULL;
00580 }
00581 return p;
00582 }
00583
00584 int WINAPI dkcFreeFile64(DKC_FILE64 **pp){
00585 DKC_FILE64 *p = *pp;
00586 if(NULL==pp || NULL==p) return edk_FAILED;
00587 if(-1 != p->handle){
00588 dkcFile64Close(p);
00589 }
00590 return dkcFree(pp);
00591 }
00592
00593 int WINAPI dkcFile64Open(DKC_FILE64 *p,uint32 flags,const void *filename)
00594 {
00595 int oflag = _O_BINARY;
00596 int mode = 0;
00597 if(NULL==p){
00598 return edk_ArgumentException;
00599 }
00600
00601 dkcFile64Close(p);
00602
00603 if(flags & edkcReadMode){
00604 oflag |= _O_RDONLY | _O_RANDOM;
00605 mode = _S_IREAD;
00606 }else if(flags & edkcWriteMode){
00607 oflag |= _O_CREAT | _O_WRONLY | _O_RANDOM | _O_TRUNC;
00608 mode = _S_IWRITE;
00609 }else if(flags & edkcPostScriptMode){
00610 oflag |= _O_RDWR | _O_RANDOM;
00611 mode = _S_IREAD | _S_IWRITE;
00612 }
00613
00614
00615
00616 oflag = _open(filename,oflag,mode);
00617 if(-1==oflag) return edk_FAILED;
00618
00619 p->handle = oflag;
00620 return edk_SUCCEEDED;
00621 }
00622
00623 DKC_INLINE int WINAPI dkcFile64Close(DKC_FILE64 *p){
00624 if(-1 == p->handle) return edk_FAILED;
00625 _close(p->handle);
00626 p->handle = -1;
00627 return edk_SUCCEEDED;
00628 }
00629
00630 int WINAPI dkcFile64Read(DKC_FILE64 *p,void *pbuff,size_t size,size_t *read_size)
00631 {
00632 int r;
00633 if(size > INT_MAX){
00634 return edk_ArgumentException;
00635 }
00636 r = _read(p->handle,pbuff,size);
00637 if(-1==r){
00638 if(errno == EBADF){
00639 return edk_LogicError;
00640 }
00641 return edk_FAILED;
00642 }
00643 *read_size = r;
00644 return edk_SUCCEEDED;
00645 }
00646
00647
00648 int WINAPI dkcFile64Write(DKC_FILE64 *p,const void *pbuff,size_t size,size_t *write_size)
00649 {
00650 int r;
00651 if(size > INT_MAX){
00652 return edk_ArgumentException;
00653 }
00654 r = _write(p->handle,pbuff,size);
00655 if(-1==r) return edk_FAILED;
00656 *write_size = r;
00657 return edk_SUCCEEDED;
00658 }
00659
00660 DKC_INLINE int WINAPI dkcFile64Seek(DKC_FILE64 *p,int64 offset,int origin){
00661 int64 t = _lseeki64( p->handle , offset, origin );
00662 if(-1==t) return edk_FAILED;
00663 return edk_SUCCEEDED;
00664 }
00665
00666 DKC_INLINE int WINAPI dkcFile64Tell(DKC_FILE64 *p,uint64 *pv)
00667 {
00668 int64 t = _telli64( p->handle );
00669 if(-1==t) return edk_FAILED;
00670 *pv = (uint64)t;
00671 return edk_SUCCEEDED;
00672 }
00673 DKC_INLINE BOOL WINAPI dkcFile64EOF(DKC_FILE64 *p){
00674 int r = _eof(p->handle);
00675
00676
00677
00678
00679
00680
00681
00682
00683 return r;
00684 }
00685
00686
00687 #ifdef _MSC_VER
00688 # pragma warning(default:4055 4152)
00689 #endif