diff options
Diffstat (limited to '7zip/Archive/7z_C/7zMain.c')
-rwxr-xr-x | 7zip/Archive/7z_C/7zMain.c | 165 |
1 files changed, 149 insertions, 16 deletions
diff --git a/7zip/Archive/7z_C/7zMain.c b/7zip/Archive/7z_C/7zMain.c index d5c5ed91..10900c54 100755 --- a/7zip/Archive/7z_C/7zMain.c +++ b/7zip/Archive/7z_C/7zMain.c @@ -1,21 +1,122 @@ /* 7zMain.c Test application for 7z Decoder -LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02) +LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04) */ #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef _WIN32 +#define USE_WINDOWS_FUNCTIONS +#endif + +#ifdef USE_WINDOWS_FUNCTIONS +#include <windows.h> +#endif + #include "7zCrc.h" #include "7zIn.h" #include "7zExtract.h" + +#ifdef USE_WINDOWS_FUNCTIONS +typedef HANDLE MY_FILE_HANDLE; +#else +typedef FILE *MY_FILE_HANDLE; +#endif + +void ConvertNumberToString(CFileSize value, char *s) +{ + char temp[32]; + int pos = 0; + do + { + temp[pos++] = (char)('0' + (int)(value % 10)); + value /= 10; + } + while (value != 0); + do + *s++ = temp[--pos]; + while(pos > 0); + *s = '\0'; +} + + +#ifdef USE_WINDOWS_FUNCTIONS +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). +#define kChunkSizeMax (1 << 24) +#endif + +size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size) +{ + if (size == 0) + return 0; + #ifdef USE_WINDOWS_FUNCTIONS + { + size_t processedSize = 0; + do + { + DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size; + DWORD processedLoc = 0; + BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL); + data = (void *)((unsigned char *)data + processedLoc); + size -= processedLoc; + processedSize += processedLoc; + if (!res || processedLoc == 0) + break; + } + while (size > 0); + return processedSize; + } + #else + return fread(data, 1, size, file); + #endif +} + +size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size) +{ + if (size == 0) + return 0; + #ifdef USE_WINDOWS_FUNCTIONS + { + size_t processedSize = 0; + do + { + DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size; + DWORD processedLoc = 0; + BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL); + data = (void *)((unsigned char *)data + processedLoc); + size -= processedLoc; + processedSize += processedLoc; + if (!res) + break; + } + while (size > 0); + return processedSize; + } + #else + return fwrite(data, 1, size, file); + #endif +} + +int MyCloseFile(MY_FILE_HANDLE file) +{ + #ifdef USE_WINDOWS_FUNCTIONS + return (CloseHandle(file) != FALSE) ? 0 : 1; + #else + return fclose(file); + #endif +} + typedef struct _CFileInStream { ISzInStream InStream; - FILE *File; + MY_FILE_HANDLE File; } CFileInStream; #ifdef _LZMA_IN_CB @@ -29,7 +130,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz size_t processedSizeLoc; if (maxRequiredSize > kBufferSize) maxRequiredSize = kBufferSize; - processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File); + processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize); *buffer = g_Buffer; if (processedSize != 0) *processedSize = processedSizeLoc; @@ -41,7 +142,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize) { CFileInStream *s = (CFileInStream *)object; - size_t processedSizeLoc = fread(buffer, 1, size, s->File); + size_t processedSizeLoc = MyReadFile(s->File, buffer, size); if (processedSize != 0) *processedSize = processedSizeLoc; return SZ_OK; @@ -52,10 +153,24 @@ SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *process SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) { CFileInStream *s = (CFileInStream *)object; + + #ifdef USE_WINDOWS_FUNCTIONS + { + LARGE_INTEGER value; + value.LowPart = (DWORD)pos; + value.HighPart = (LONG)(pos >> 32); + value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN); + if (value.LowPart == 0xFFFFFFFF) + if(GetLastError() != NO_ERROR) + return SZE_FAIL; + return SZ_OK; + } + #else int res = fseek(s->File, (long)pos, SEEK_SET); if (res == 0) return SZ_OK; return SZE_FAIL; + #endif } void PrintError(char *sz) @@ -71,7 +186,7 @@ int main(int numargs, char *args[]) ISzAlloc allocImp; ISzAlloc allocTempImp; - printf("\n7z ANSI-C Decoder 4.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n"); + printf("\n7z ANSI-C Decoder 4.44 Copyright (c) 1999-2006 Igor Pavlov 2006-08-27\n"); if (numargs == 1) { printf( @@ -88,8 +203,15 @@ int main(int numargs, char *args[]) return 1; } + archiveStream.File = + #ifdef USE_WINDOWS_FUNCTIONS + CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (archiveStream.File == INVALID_HANDLE_VALUE) + #else archiveStream.File = fopen(args[2], "rb"); if (archiveStream.File == 0) + #endif { PrintError("can not open input file"); return 1; @@ -126,18 +248,22 @@ int main(int numargs, char *args[]) for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; - printf("%10d %s\n", (int)f->Size, f->Name); + char s[32]; + ConvertNumberToString(f->Size, s); + printf("%10s %s\n", s, f->Name); } } else if (testCommand || extractCommand) { UInt32 i; - // if you need cache, use these 3 variables. - // if you use external function, you can make these variable as static. - UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0) - Byte *outBuffer = 0; // it must be 0 before first call for each new archive. - size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0) + /* + if you need cache, use these 3 variables. + if you use external function, you can make these variable as static. + */ + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ + Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ + size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ printf("\n"); for (i = 0; i < db.Database.NumFiles; i++) @@ -165,7 +291,7 @@ int main(int numargs, char *args[]) break; if (!testCommand) { - FILE *outputHandle; + MY_FILE_HANDLE outputHandle; UInt32 processedSize; char *fileName = f->Name; size_t nameLen = strlen(f->Name); @@ -176,21 +302,28 @@ int main(int numargs, char *args[]) break; } - outputHandle = fopen(fileName, "wb+"); + outputHandle = + #ifdef USE_WINDOWS_FUNCTIONS + CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (outputHandle == INVALID_HANDLE_VALUE) + #else + fopen(fileName, "wb+"); if (outputHandle == 0) + #endif { PrintError("can not open output file"); res = SZE_FAIL; break; } - processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle); + processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed); if (processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZE_FAIL; break; } - if (fclose(outputHandle)) + if (MyCloseFile(outputHandle)) { PrintError("can not close output file"); res = SZE_FAIL; @@ -209,7 +342,7 @@ int main(int numargs, char *args[]) } SzArDbExFree(&db, allocImp.Free); - fclose(archiveStream.File); + MyCloseFile(archiveStream.File); if (res == SZ_OK) { printf("\nEverything is Ok\n"); |