├── res ├── local.flag ├── nolocal.flag ├── stub.ico ├── bat2exe.rc ├── bat2exeres.h ├── resource.h ├── stub.bat └── stub.rc ├── lib ├── snappy.lib ├── libsnappy.lib └── libsnappy.la ├── ReadMe.md ├── src ├── compile.h ├── common.h ├── bat2exe.c ├── compile.c └── stub.c └── include ├── snappy-stubs-public.h ├── snappy-sinksource.h ├── snappy-c.h └── snappy.h /res/local.flag: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /res/nolocal.flag: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /res/stub.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juntalis/win32-bat2exe/HEAD/res/stub.ico -------------------------------------------------------------------------------- /lib/snappy.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juntalis/win32-bat2exe/HEAD/lib/snappy.lib -------------------------------------------------------------------------------- /res/bat2exe.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juntalis/win32-bat2exe/HEAD/res/bat2exe.rc -------------------------------------------------------------------------------- /lib/libsnappy.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juntalis/win32-bat2exe/HEAD/lib/libsnappy.lib -------------------------------------------------------------------------------- /res/bat2exeres.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juntalis/win32-bat2exe/HEAD/res/bat2exeres.h -------------------------------------------------------------------------------- /res/resource.h: -------------------------------------------------------------------------------- 1 | #ifndef IDC_STATIC 2 | #define IDC_STATIC (-1) 3 | #endif 4 | 5 | #define IDI_APPICON 1 6 | #define IDR_EXECLOCAL_FLAG 105 7 | #define IDR_DEFAULT_EXEC 106 8 | -------------------------------------------------------------------------------- /res/stub.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | setlocal 3 | echo This is a generic stub. 4 | set 5 | set /A ARGN=0 6 | goto Loop 7 | :Loop 8 | if "%0x"=="x" goto EndLoop 9 | echo %%%ARGN%=%0 10 | set /A ARGN+=1 11 | shift /0 12 | goto Loop 13 | :EndLoop 14 | endlocal 15 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | #Bat2Exe 2 | 3 | Wanted to try my hand at making one really quick, and I figured I'd share for anyone who didn't know how existing compilers work. 4 | 5 | Run build.bat, and it should compile. If not, let me know. The current source uses the [Snappy compression lib](http://code.google.com/p/snappy/) which I've added a compiled lib for. 6 | 7 | The compiled stub.exe uncompresses an embedded bat file from its resources at runtime, then executes it in the current console before deleting the temporary file created. 8 | 9 | The compiled bat2exe.exe file has a copy of stub.exe embedded in its resource file. On runtime, it extracts stub.exe, then updates the existing embedded .bat script with the new script that the user specified. 10 | 11 | Sorry for the crappy code and lack of documentation. -------------------------------------------------------------------------------- /res/stub.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "resource.h" 5 | /* 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | #include "afxres.h" 8 | #undef APSTUDIO_READONLY_SYMBOLS */ 9 | 10 | #ifndef NO_COMPRESSION 11 | LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT 12 | IDR_DEFAULT_EXEC EXEC "stub.bat.bin" 13 | #else 14 | LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT 15 | IDR_DEFAULT_EXEC EXEC "stub.bat" 16 | #endif 17 | 18 | #ifndef EXEC_LOCAL 19 | LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT 20 | IDR_EXECLOCAL_FLAG FLAGS "nolocal.flag" 21 | #else 22 | LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT 23 | IDR_EXECLOCAL_FLAG FLAGS "local.flag" 24 | #endif 25 | 26 | 27 | // 28 | // Icon resources 29 | // 30 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 31 | IDI_APPICON ICON "stub.ico" 32 | -------------------------------------------------------------------------------- /src/compile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define STUB_RC "res\\stub.rc" 4 | #define EDIT_RC "res\\bat2exe.rc" 5 | #define STUB_RES "obj\\stub.res" 6 | #define EDIT_RES "obj\\bat2exe.res" 7 | #define RC_CMD "rc.exe -nologo -fo" STUB_RES " " 8 | #define RC_EDIT_CMD "rc.exe -nologo -fo" EDIT_RES " " 9 | #define RC_NO_COMPRESS "-dNO_COMPRESSION=1 " 10 | #define RC_EXEC_LOCAL "-dEXEC_LOCAL=1 " 11 | #define STUB_OBJ "obj\\stub.obj" 12 | #define EDIT_OBJ "obj\\bat2exe.obj" 13 | #define CL_CMD "cl.exe -nologo -Fo" STUB_OBJ " -Ires -Isrc -Iinclude " 14 | #define CL_EDIT_CMD "cl.exe -nologo -Fo" EDIT_OBJ " -Ires -Isrc -Iinclude " 15 | #define CL_NO_COMPRESS "-DNO_COMPRESSION=1 " 16 | #define CL_EXEC_LOCAL "-DEXEC_LOCAL=1 " 17 | #define STUB_C "src\\stub.c" 18 | #define EDIT_C "src\\bat2exe.c" 19 | #define CL_END STUB_C " " STUB_RES " -link -LIBPATH:lib -LTCG -OPT:REF -OPT:ICF" 20 | #define CL_EDIT_END EDIT_C " " EDIT_RES " -link -LIBPATH:lib -LTCG -OPT:REF -OPT:ICF" -------------------------------------------------------------------------------- /lib/libsnappy.la: -------------------------------------------------------------------------------- 1 | # libsnappy.la - a libtool library file 2 | # Generated by ltmain.sh (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1 3 | # 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # The name that we can dlopen(3). 8 | dlname='' 9 | 10 | # Names of this library. 11 | library_names='' 12 | 13 | # The name of the static archive. 14 | old_library='libsnappy.lib' 15 | 16 | # Linker flags that can not go in dependency_libs. 17 | inherited_linker_flags='' 18 | 19 | # Libraries that this one depends upon. 20 | dependency_libs='' 21 | 22 | # Names of additional weak libraries provided by this library 23 | weak_library_names='' 24 | 25 | # Version information for libsnappy. 26 | current=2 27 | age=1 28 | revision=2 29 | 30 | # Is this an already installed library? 31 | installed=no 32 | 33 | # Should we warn about portability when linking against -modules? 34 | shouldnotlink=no 35 | 36 | # Files to dlopen/dlpreopen 37 | dlopen='' 38 | dlpreopen='' 39 | 40 | # Directory that this library needs to be installed in: 41 | libdir='/usr/local/lib' 42 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // Target Windows 2000 & higher 5 | #define WINVER 0x0500 6 | #define _WIN32_WINNT 0x0500 7 | 8 | // Set to use multibyte characters. 9 | #define _MBCS 1 10 | 11 | // Speed up build process with minimal headers. 12 | #define WIN32_LEAN_AND_MEAN 13 | #define VC_EXTRALEAN 14 | 15 | // Eliminate some warnings. 16 | #ifndef _CRT_SECURE_NO_WARNINGS 17 | # define _CRT_SECURE_NO_WARNINGS 18 | #endif 19 | 20 | #ifndef _CRT_NONSTDC_NO_WARNINGS 21 | # define _CRT_NONSTDC_NO_WARNINGS 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #ifndef NO_COMPRESSION 29 | #pragma comment(lib, "snappy.lib") 30 | #include "snappy-c.h" 31 | #endif 32 | 33 | #define STUB_IN "res\\stub.bat" 34 | #define STUB_OUT "res\\stub.bat.bin" 35 | 36 | #define fatal(M,...) printf("Error: " M "\n",__VA_ARGS__); exit(EXIT_FAILURE) 37 | #define error(M,...) printf("Error: " M "\n",__VA_ARGS__) 38 | #define out(M,...) printf(M,__VA_ARGS__) 39 | #define outl(M) printf("%s\n", M) 40 | 41 | #ifndef bool 42 | # define bool BOOL 43 | # define true TRUE 44 | # define false FALSE 45 | #endif 46 | 47 | #ifdef _DEBUG 48 | # define debug(M,...) printf(M "\n",__VA_ARGS__) 49 | #else 50 | # define debug(M,...) 51 | #endif 52 | -------------------------------------------------------------------------------- /include/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 1 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #define SNAPPY_MAJOR 1 48 | #define SNAPPY_MINOR 0 49 | #define SNAPPY_PATCHLEVEL 4 50 | #define SNAPPY_VERSION \ 51 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 52 | 53 | #include 54 | 55 | namespace snappy { 56 | 57 | #if 1 58 | typedef int8_t int8; 59 | typedef uint8_t uint8; 60 | typedef int16_t int16; 61 | typedef uint16_t uint16; 62 | typedef int32_t int32; 63 | typedef uint32_t uint32; 64 | typedef int64_t int64; 65 | typedef uint64_t uint64; 66 | #else 67 | typedef signed char int8; 68 | typedef unsigned char uint8; 69 | typedef short int16; 70 | typedef unsigned short uint16; 71 | typedef int int32; 72 | typedef unsigned int uint32; 73 | typedef long long int64; 74 | typedef unsigned long long uint64; 75 | #endif 76 | 77 | typedef std::string string; 78 | 79 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 80 | TypeName(const TypeName&); \ 81 | void operator=(const TypeName&) 82 | 83 | } // namespace snappy 84 | 85 | #endif // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 86 | -------------------------------------------------------------------------------- /include/snappy-sinksource.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #ifndef UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ 30 | #define UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ 31 | 32 | #include 33 | 34 | 35 | namespace snappy { 36 | 37 | // A Sink is an interface that consumes a sequence of bytes. 38 | class Sink { 39 | public: 40 | Sink() { } 41 | virtual ~Sink(); 42 | 43 | // Append "bytes[0,n-1]" to this. 44 | virtual void Append(const char* bytes, size_t n) = 0; 45 | 46 | // Returns a writable buffer of the specified length for appending. 47 | // May return a pointer to the caller-owned scratch buffer which 48 | // must have at least the indicated length. The returned buffer is 49 | // only valid until the next operation on this Sink. 50 | // 51 | // After writing at most "length" bytes, call Append() with the 52 | // pointer returned from this function and the number of bytes 53 | // written. Many Append() implementations will avoid copying 54 | // bytes if this function returned an internal buffer. 55 | // 56 | // If a non-scratch buffer is returned, the caller may only pass a 57 | // prefix of it to Append(). That is, it is not correct to pass an 58 | // interior pointer of the returned array to Append(). 59 | // 60 | // The default implementation always returns the scratch buffer. 61 | virtual char* GetAppendBuffer(size_t length, char* scratch); 62 | 63 | private: 64 | // No copying 65 | Sink(const Sink&); 66 | void operator=(const Sink&); 67 | }; 68 | 69 | // A Source is an interface that yields a sequence of bytes 70 | class Source { 71 | public: 72 | Source() { } 73 | virtual ~Source(); 74 | 75 | // Return the number of bytes left to read from the source 76 | virtual size_t Available() const = 0; 77 | 78 | // Peek at the next flat region of the source. Does not reposition 79 | // the source. The returned region is empty iff Available()==0. 80 | // 81 | // Returns a pointer to the beginning of the region and store its 82 | // length in *len. 83 | // 84 | // The returned region is valid until the next call to Skip() or 85 | // until this object is destroyed, whichever occurs first. 86 | // 87 | // The returned region may be larger than Available() (for example 88 | // if this ByteSource is a view on a substring of a larger source). 89 | // The caller is responsible for ensuring that it only reads the 90 | // Available() bytes. 91 | virtual const char* Peek(size_t* len) = 0; 92 | 93 | // Skip the next n bytes. Invalidates any buffer returned by 94 | // a previous call to Peek(). 95 | // REQUIRES: Available() >= n 96 | virtual void Skip(size_t n) = 0; 97 | 98 | private: 99 | // No copying 100 | Source(const Source&); 101 | void operator=(const Source&); 102 | }; 103 | 104 | // A Source implementation that yields the contents of a flat array 105 | class ByteArraySource : public Source { 106 | public: 107 | ByteArraySource(const char* p, size_t n) : ptr_(p), left_(n) { } 108 | virtual ~ByteArraySource(); 109 | virtual size_t Available() const; 110 | virtual const char* Peek(size_t* len); 111 | virtual void Skip(size_t n); 112 | private: 113 | const char* ptr_; 114 | size_t left_; 115 | }; 116 | 117 | // A Sink implementation that writes to a flat array without any bound checks. 118 | class UncheckedByteArraySink : public Sink { 119 | public: 120 | explicit UncheckedByteArraySink(char* dest) : dest_(dest) { } 121 | virtual ~UncheckedByteArraySink(); 122 | virtual void Append(const char* data, size_t n); 123 | virtual char* GetAppendBuffer(size_t len, char* scratch); 124 | 125 | // Return the current output pointer so that a caller can see how 126 | // many bytes were produced. 127 | // Note: this is not a Sink method. 128 | char* CurrentDestination() const { return dest_; } 129 | private: 130 | char* dest_; 131 | }; 132 | 133 | 134 | } 135 | 136 | #endif // UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ 137 | -------------------------------------------------------------------------------- /include/snappy-c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Martin Gieseking . 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Google Inc. nor the names of its 15 | * contributors may be used to endorse or promote products derived from 16 | * this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | * Plain C interface (a wrapper around the C++ implementation). 31 | */ 32 | 33 | #ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ 34 | #define UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | #include 41 | 42 | /* 43 | * Return values; see the documentation for each function to know 44 | * what each can return. 45 | */ 46 | typedef enum { 47 | SNAPPY_OK = 0, 48 | SNAPPY_INVALID_INPUT = 1, 49 | SNAPPY_BUFFER_TOO_SMALL = 2, 50 | } snappy_status; 51 | 52 | /* 53 | * Takes the data stored in "input[0..input_length-1]" and stores 54 | * it in the array pointed to by "compressed". 55 | * 56 | * signals the space available in "compressed". 57 | * If it is not at least equal to "snappy_max_compressed_length(input_length)", 58 | * SNAPPY_BUFFER_TOO_SMALL is returned. After successful compression, 59 | * contains the true length of the compressed output, 60 | * and SNAPPY_OK is returned. 61 | * 62 | * Example: 63 | * size_t output_length = snappy_max_compressed_length(input_length); 64 | * char* output = (char*)malloc(output_length); 65 | * if (snappy_compress(input, input_length, output, &output_length) 66 | * == SNAPPY_OK) { 67 | * ... Process(output, output_length) ... 68 | * } 69 | * free(output); 70 | */ 71 | snappy_status snappy_compress(const char* input, 72 | size_t input_length, 73 | char* compressed, 74 | size_t* compressed_length); 75 | 76 | /* 77 | * Given data in "compressed[0..compressed_length-1]" generated by 78 | * calling the snappy_compress routine, this routine stores 79 | * the uncompressed data to 80 | * uncompressed[0..uncompressed_length-1]. 81 | * Returns failure (a value not equal to SNAPPY_OK) if the message 82 | * is corrupted and could not be decrypted. 83 | * 84 | * signals the space available in "uncompressed". 85 | * If it is not at least equal to the value returned by 86 | * snappy_uncompressed_length for this stream, SNAPPY_BUFFER_TOO_SMALL 87 | * is returned. After successful decompression, 88 | * contains the true length of the decompressed output. 89 | * 90 | * Example: 91 | * size_t output_length; 92 | * if (snappy_uncompressed_length(input, input_length, &output_length) 93 | * != SNAPPY_OK) { 94 | * ... fail ... 95 | * } 96 | * char* output = (char*)malloc(output_length); 97 | * if (snappy_uncompress(input, input_length, output, &output_length) 98 | * == SNAPPY_OK) { 99 | * ... Process(output, output_length) ... 100 | * } 101 | * free(output); 102 | */ 103 | snappy_status snappy_uncompress(const char* compressed, 104 | size_t compressed_length, 105 | char* uncompressed, 106 | size_t* uncompressed_length); 107 | 108 | /* 109 | * Returns the maximal size of the compressed representation of 110 | * input data that is "source_length" bytes in length. 111 | */ 112 | size_t snappy_max_compressed_length(size_t source_length); 113 | 114 | /* 115 | * REQUIRES: "compressed[]" was produced by snappy_compress() 116 | * Returns SNAPPY_OK and stores the length of the uncompressed data in 117 | * *result normally. Returns SNAPPY_INVALID_INPUT on parsing error. 118 | * This operation takes O(1) time. 119 | */ 120 | snappy_status snappy_uncompressed_length(const char* compressed, 121 | size_t compressed_length, 122 | size_t* result); 123 | 124 | /* 125 | * Check if the contents of "compressed[]" can be uncompressed successfully. 126 | * Does not return the uncompressed data; if so, returns SNAPPY_OK, 127 | * or if not, returns SNAPPY_INVALID_INPUT. 128 | * Takes time proportional to compressed_length, but is usually at least a 129 | * factor of four faster than actual decompression. 130 | */ 131 | snappy_status snappy_validate_compressed_buffer(const char* compressed, 132 | size_t compressed_length); 133 | 134 | #ifdef __cplusplus 135 | } // extern "C" 136 | #endif 137 | 138 | #endif /* UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */ 139 | -------------------------------------------------------------------------------- /src/bat2exe.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include "resource.h" 5 | #include "bat2exeres.h" 6 | 7 | static char* exe_name = NULL; 8 | 9 | static void exit_usage(int status) 10 | { 11 | out("Usage: %s [[--temp|-t]|[--local|-l]] [-h|--help] file.bat file.exe\n\n" 12 | " --local, -l Execute the bat file from the same file as exe. (Affects %%0)\n" 13 | " --temp, -t Execute the bat file from temporary folder. (Affects %%0)\n" 14 | " --help, -h Print this message\n", exe_name); 15 | exit(status); 16 | } 17 | 18 | #define access _access 19 | #define fgetcnl _fgetc_nolock 20 | #define ftellnl _ftell_nolock 21 | #define fseeknl _fseek_nolock 22 | size_t get_file_length(FILE* pFile) 23 | { 24 | long lCurrPos, lEndPos; 25 | size_t result = -1; 26 | lCurrPos = ftellnl(pFile); 27 | if(lCurrPos == -1) 28 | return result; 29 | if(fseeknl(pFile, 0L, SEEK_END) == -1) 30 | return result; 31 | lEndPos = ftellnl(pFile); 32 | if(lEndPos == -1) 33 | return result; 34 | result = (size_t)(lEndPos - lCurrPos); 35 | if(fseeknl(pFile, 0L, SEEK_SET) == -1) 36 | return -1; 37 | return result; 38 | } 39 | 40 | static bool end_update(HANDLE hExe, char* inexe) 41 | { 42 | 43 | if(!EndUpdateResource(hExe, FALSE)) { 44 | error("Could not update %s.", inexe); 45 | return false; 46 | } 47 | return true; 48 | } 49 | 50 | static bool change_exec_location(HANDLE hExe, char* inexe, int exec_type) 51 | { 52 | const char* exec_flag = exec_type ? "0" : "1"; 53 | if(!UpdateResource(hExe, "FLAGS", MAKEINTRESOURCE(IDR_EXECLOCAL_FLAG), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPVOID)exec_flag, (DWORD)sizeof(char) * 2)) { 54 | error("Could not update resource in %s.", inexe); 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | static bool change_batchfile(HANDLE hExe, char* inexe, char* inbat) 61 | { 62 | FILE* fwork; 63 | char* output; 64 | char* input; 65 | size_t output_length; 66 | size_t input_length; 67 | 68 | if((fwork = fopen(inbat, "rb")) == NULL) { 69 | error("Failed to open input file."); 70 | return false; 71 | } 72 | 73 | if((input_length = get_file_length(fwork)) == -1) { 74 | error("Could not get filesize of %s.", inbat); 75 | return false; 76 | } 77 | 78 | input = (char*)malloc((input_length+1)*sizeof(char)); 79 | memset((void*)input, 0, (input_length+1)*sizeof(char)); 80 | if(input == NULL) { 81 | error("Could not allocate buffer for uncompressed data."); 82 | return false; 83 | } 84 | 85 | if(!fread((void*)input, sizeof(char), input_length, fwork)) { 86 | free(input); 87 | error("Failed to read input file."); 88 | return false; 89 | } 90 | 91 | fclose(fwork); 92 | output_length = snappy_max_compressed_length(input_length); 93 | output = (char*)malloc(output_length); 94 | if(output == NULL) { 95 | free(input); 96 | error("Could not allocate buffer for compressed data."); 97 | return false; 98 | } 99 | 100 | if (snappy_compress(input, input_length, output, &output_length) == SNAPPY_OK) { 101 | free(input); 102 | outl("Successfully compressed data."); 103 | if(!UpdateResource( 104 | hExe, // update resource handle 105 | "EXEC", // type 106 | MAKEINTRESOURCE(IDR_DEFAULT_EXEC), // name 107 | MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), // language 108 | (LPVOID)output, // ptr to resource info 109 | (DWORD)output_length)) {// size of resource info. 110 | free(output); 111 | error("Could not update resource in %s.", inexe); 112 | return false; 113 | } 114 | } else { 115 | free(input); 116 | free(output); 117 | error("Failed to compress stub file."); 118 | return false; 119 | } 120 | 121 | free(output); 122 | return end_update(hExe, inexe); 123 | } 124 | 125 | int main(int argc, char* argv[]) 126 | { 127 | HANDLE hExe; 128 | int exec_type = -1; 129 | FILE* fwork; 130 | char* inexe = NULL; 131 | char* inbat = NULL; 132 | const char* data = NULL; 133 | HRSRC hrsrc; 134 | HGLOBAL hglb; 135 | LPBYTE bindata; 136 | size_t data_len = 0; 137 | int i = 0; 138 | 139 | exe_name = argv[0]; 140 | for(i = 1; i < argc; i++) { 141 | if((_stricmp(argv[i], "--local") == 0) || (_stricmp(argv[i], "-l") == 0)) { 142 | exec_type = 0; 143 | } else if((_stricmp(argv[i], "--temp") == 0) || (_stricmp(argv[i], "-t") == 0)) { 144 | exec_type = 1; 145 | } else if((_stricmp(argv[i], "--help") == 0)||(_stricmp(argv[i], "-h") == 0)) { 146 | exit_usage(EXIT_SUCCESS); 147 | } else if(inbat == NULL) { 148 | inbat = argv[i]; 149 | } else if(inexe == NULL) { 150 | inexe = argv[i]; 151 | } else { 152 | error("Extra argument added."); 153 | exit_usage(EXIT_FAILURE); 154 | } 155 | } 156 | if(((inbat == NULL) || (inexe == NULL)) && (exec_type == -1)) { 157 | error("Missing an input."); 158 | exit_usage(EXIT_FAILURE); 159 | } 160 | 161 | if(_access(inbat, 00) != 0) { 162 | fatal("%s does not exist.", inbat); 163 | } 164 | 165 | if(_access(inexe, 00) != 0) { 166 | hrsrc = FindResource(NULL, "IDR_CONSOLE_BAT", "STUBS"); 167 | if (hrsrc && (hglb = LoadResource(NULL, hrsrc))) { 168 | bindata = (LPBYTE)LockResource(hglb); 169 | data_len = (size_t)SizeofResource(NULL, hrsrc); 170 | data = (const char*)malloc(sizeof(const char) * data_len); 171 | if(data == NULL) { 172 | fatal("Could not allocate buffer for compressed data."); 173 | } 174 | memcpy((void*)data, (const void*)bindata, data_len); 175 | if((fwork = fopen(inexe, "wb")) == NULL) { 176 | free((void*)data); 177 | fatal("Could not open new exe file: %s", inexe); 178 | } 179 | if(!fwrite((const void*)data, sizeof(char), data_len / sizeof(char), fwork)) { 180 | fclose(fwork); 181 | free((void*)data); 182 | fatal("Failed to write to exe file: %s.", inexe); 183 | } 184 | fclose(fwork); 185 | free((void*)data); 186 | } else { 187 | fatal("Could not find and load packaged data."); 188 | } 189 | } 190 | 191 | hExe = BeginUpdateResource(inexe, TRUE); 192 | if(hExe == NULL) { 193 | fatal("Could not open %s for updating.", inexe); 194 | } 195 | 196 | if(exec_type != -1) 197 | if(!change_exec_location(hExe, inexe, exec_type)) 198 | return EXIT_FAILURE; 199 | 200 | if(!change_batchfile(hExe, inexe, inbat)) 201 | return EXIT_FAILURE; 202 | out("Successsfully created exe.\n"); 203 | return EXIT_SUCCESS; 204 | } -------------------------------------------------------------------------------- /src/compile.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "compile.h" 3 | #include 4 | #include 5 | 6 | 7 | #define access _access 8 | #define fgetcnl _fgetc_nolock 9 | #define ftellnl _ftell_nolock 10 | #define fseeknl _fseek_nolock 11 | size_t get_file_length(FILE* pFile) 12 | { 13 | long lCurrPos, lEndPos; 14 | size_t result = -1; 15 | lCurrPos = ftellnl(pFile); 16 | if(lCurrPos == -1) 17 | return result; 18 | if(fseeknl(pFile, 0L, SEEK_END) == -1) 19 | return result; 20 | lEndPos = ftellnl(pFile); 21 | if(lEndPos == -1) 22 | return result; 23 | result = (size_t)(lEndPos - lCurrPos); 24 | if(fseeknl(pFile, 0L, SEEK_SET) == -1) 25 | return -1; 26 | return result; 27 | } 28 | 29 | int main(int argc, char* argv[]) 30 | { 31 | char* output; 32 | char* input; 33 | FILE* fwork; 34 | size_t output_length; 35 | size_t input_length; 36 | size_t execlen = 0; 37 | int result = 0; 38 | char* cflags = NULL; 39 | char* exec_cmd = NULL; 40 | char rc_cmd[128] = "\0"; 41 | bool no_compression = false; 42 | bool exec_temp = false; 43 | int i = 0; 44 | 45 | if(_access("obj", 00) != 0) { 46 | if(_mkdir("obj") != 0) { 47 | fatal("Could not create intermediate folder."); 48 | } 49 | } 50 | 51 | for(i = 1; i < argc; i++) { 52 | if((_stricmp(argv[i], "--no-compression") == 0) || (_stricmp(argv[i], "-n") == 0)){ 53 | no_compression = true; 54 | } else if((_stricmp(argv[i], "--no-local") == 0) || (_stricmp(argv[i], "-l") == 0)) { 55 | exec_temp = true; 56 | } else if((_stricmp(argv[i], "--help") == 0)||(_stricmp(argv[i], "-h") == 0)) { 57 | out("Usage: %s [--no-compression|-n] [--no-local|-l] [-h|--help]\n", argv[0]); 58 | exit(0); 59 | } 60 | } 61 | 62 | if(_access(STUB_OUT, 00) == 0) _unlink(STUB_OUT); 63 | 64 | if((fwork = fopen(STUB_IN, "rb")) == NULL) { 65 | fatal("Failed to open input file."); 66 | } 67 | 68 | if((input_length = get_file_length(fwork)) == -1) { 69 | fatal("Could not get filesize of " STUB_IN "."); 70 | } 71 | 72 | input = (char*)malloc((input_length+1)*sizeof(char)); 73 | memset((void*)input, 0, (input_length+1)*sizeof(char)); 74 | if(input == NULL) { 75 | fatal("Could not allocate buffer for uncompressed data."); 76 | } 77 | 78 | if(!fread((void*)input, sizeof(char), input_length, fwork)) { 79 | free(input); 80 | fatal("Failed to read input file."); 81 | } 82 | 83 | fclose(fwork); 84 | output_length = snappy_max_compressed_length(input_length); 85 | output = (char*)malloc(output_length); 86 | if(output == NULL) { 87 | free(input); 88 | fatal("Could not allocate buffer for compressed data."); 89 | } 90 | 91 | if (snappy_compress(input, input_length, output, &output_length) == SNAPPY_OK) { 92 | free(input); 93 | outl("Compressed data."); 94 | if((fwork = fopen(STUB_OUT, "wb")) == NULL) { 95 | fatal("Failed to open output file."); 96 | } 97 | if(!fwrite((const void*)output, sizeof(char), output_length / sizeof(char), fwork)) { 98 | fatal("Failed to write to output file."); 99 | } 100 | fclose(fwork); 101 | } else { 102 | free(input); 103 | free(output); 104 | fatal("Failed to compress stub file."); 105 | } 106 | free(output); 107 | 108 | if(_access(STUB_OBJ, 00) == 0) _unlink(STUB_OBJ); 109 | if(_access(EDIT_OBJ, 00) == 0) _unlink(EDIT_OBJ); 110 | if(_access(STUB_RES, 00) == 0) _unlink(STUB_RES); 111 | if(_access(EDIT_RES, 00) == 0) _unlink(EDIT_RES); 112 | 113 | // Compile stub.rc 114 | outl("\nCompiling resource file."); 115 | strcpy(rc_cmd, RC_CMD); 116 | if(!exec_temp) strcat(rc_cmd, RC_EXEC_LOCAL); 117 | if(no_compression) strcat(rc_cmd, RC_NO_COMPRESS); 118 | strcat(rc_cmd, STUB_RC); 119 | 120 | if((result = system(rc_cmd)) != EXIT_SUCCESS) { 121 | fatal("Failed to compile " STUB_RC "\n\nrc.exe returned code %d", result); 122 | } 123 | 124 | 125 | // cl.exe -Foobj\stub.obj src\stub.c obj\stub.res -link -LTCG -OPT:REF -OPT:ICF\0 126 | execlen = strlen(CL_CMD CL_END); 127 | if((cflags = getenv("CFLAGS")) != NULL) { 128 | execlen += lstrlenA(cflags) + 1; 129 | } 130 | 131 | if(!exec_temp) execlen += 15; 132 | if(no_compression) execlen += 19; 133 | 134 | exec_cmd = (char*)malloc(sizeof(char) * execlen); 135 | if(exec_cmd == NULL) { 136 | fatal("Could not allocate buffer for command-line."); 137 | } 138 | 139 | memset((void*)exec_cmd, 0, sizeof(char) * execlen); 140 | strcpy(exec_cmd, CL_CMD); 141 | if(cflags != NULL) { 142 | strcat(exec_cmd, cflags); 143 | strcat(exec_cmd, " "); 144 | } 145 | if(!exec_temp) { 146 | out("Enabling local-exec.\n"); 147 | strcat(exec_cmd, CL_EXEC_LOCAL); 148 | } 149 | if(no_compression) { 150 | out("Enabling resource compression.\n"); 151 | strcat(exec_cmd, CL_NO_COMPRESS); 152 | } 153 | 154 | strcat(exec_cmd, CL_END); 155 | 156 | outl("Compiling source files.\n"); 157 | if((result = system(exec_cmd)) != EXIT_SUCCESS) { 158 | free(exec_cmd); 159 | fatal("Failed to compile stub.c\n\ncl.exe returned code %d", result); 160 | } 161 | free(exec_cmd); 162 | 163 | // Compile bat2exe.rc 164 | strcpy(rc_cmd, ""); 165 | outl("\nCompiling resource file."); 166 | strcpy(rc_cmd, RC_EDIT_CMD); 167 | if(!exec_temp) strcat(rc_cmd, RC_EXEC_LOCAL); 168 | if(no_compression) strcat(rc_cmd, RC_NO_COMPRESS); 169 | strcat(rc_cmd, EDIT_RC); 170 | 171 | if((result = system(rc_cmd)) != EXIT_SUCCESS) { 172 | fatal("Failed to compile " EDIT_RC "\n\nrc.exe returned code %d", result); 173 | } 174 | 175 | // cl.exe %CFLAGS% -Foobj\bat2exe.obj src\bat2exe.c obj\bat2exe.res -link -LTCG -OPT:REF -OPT:ICF\0 176 | execlen = strlen(CL_EDIT_CMD CL_EDIT_END); 177 | if((cflags = getenv("CFLAGS")) != NULL) { 178 | execlen += lstrlenA(cflags) + 1; 179 | } 180 | 181 | if(!exec_temp) execlen += 15; 182 | if(no_compression) execlen += 19; 183 | 184 | exec_cmd = (char*)malloc(sizeof(char) * execlen); 185 | if(exec_cmd == NULL) { 186 | fatal("Could not allocate buffer for command-line."); 187 | } 188 | memset((void*)exec_cmd, 0, sizeof(char) * execlen); 189 | strcpy(exec_cmd, CL_EDIT_CMD); 190 | if(cflags != NULL) { 191 | strcat(exec_cmd, cflags); 192 | strcat(exec_cmd, " "); 193 | } 194 | if(!exec_temp) { 195 | out("Enabling local-exec.\n"); 196 | strcat(exec_cmd, CL_EXEC_LOCAL); 197 | } 198 | if(no_compression) { 199 | out("Enabling resource compression.\n"); 200 | strcat(exec_cmd, CL_NO_COMPRESS); 201 | } 202 | strcat(exec_cmd, CL_EDIT_END); 203 | if((result = system(exec_cmd)) != EXIT_SUCCESS) { 204 | free(exec_cmd); 205 | fatal("Failed to compile batcompile.c\n\ncl.exe returned code %d", result); 206 | } 207 | free(exec_cmd); 208 | return 0; 209 | } -------------------------------------------------------------------------------- /src/stub.c: -------------------------------------------------------------------------------- 1 | #pragma comment(lib, "psapi.lib") 2 | #include "common.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "resource.h" 8 | #include 9 | 10 | static char thisPath[_MAX_PATH] = "\0"; 11 | 12 | // Search each process in the snapshot for id. 13 | static bool find_proc_id( HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe ) 14 | { 15 | bool fOk = false; 16 | ppe->dwSize = sizeof(PROCESSENTRY32); 17 | for (fOk = Process32First( snap, ppe ); fOk; fOk = Process32Next( snap, ppe )) 18 | if (ppe->th32ProcessID == id) 19 | break; 20 | 21 | return fOk; 22 | } 23 | 24 | // Search each process in the snapshot for id. 25 | static bool find_proc_name( HANDLE snap, DWORD id, LPMODULEENTRY32 pme ) 26 | { 27 | bool fOk = false; 28 | char myPath[_MAX_PATH]; 29 | if(!GetModuleFileNameA(NULL, myPath, _MAX_PATH)) { 30 | fatal("Could not get path of current executable."); 31 | } 32 | pme->dwSize = sizeof(MODULEENTRY32); 33 | for (fOk = Module32First( snap, pme ); fOk; fOk = Module32Next( snap, pme )) { 34 | if (pme->th32ModuleID == id) { 35 | if (_stricmp(pme->szExePath, myPath) == 0) { 36 | fOk = false; 37 | } 38 | break; 39 | } 40 | } 41 | return fOk; 42 | } 43 | 44 | // Obtain the process and thread identifiers of the parent process. 45 | static bool get_parent( LPPROCESS_INFORMATION ppi ) 46 | { 47 | HANDLE hSnap; 48 | PROCESSENTRY32 pe; 49 | THREADENTRY32 te; 50 | DWORD id = GetCurrentProcessId(); 51 | bool fOk; 52 | 53 | 54 | hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD, id ); 55 | if (hSnap == INVALID_HANDLE_VALUE) 56 | return false; 57 | 58 | find_proc_id( hSnap, id, &pe ); 59 | if (!find_proc_id( hSnap, pe.th32ParentProcessID, &pe )) { 60 | CloseHandle( hSnap ); 61 | return false; 62 | } 63 | 64 | while(_stricmp(pe.szExeFile, "cmd.exe") == 0) { 65 | if (!find_proc_id( hSnap, pe.th32ParentProcessID, &pe )) { 66 | CloseHandle( hSnap ); 67 | return false; 68 | } 69 | } 70 | 71 | te.dwSize = sizeof(te); 72 | for (fOk = Thread32First( hSnap, &te ); fOk; fOk = Thread32Next( hSnap, &te )) 73 | if (te.th32OwnerProcessID == pe.th32ProcessID) 74 | break; 75 | 76 | CloseHandle(hSnap); 77 | ppi->dwProcessId = pe.th32ProcessID; 78 | ppi->dwThreadId = te.th32ThreadID; 79 | 80 | return fOk; 81 | } 82 | 83 | static bool eliminate_recursion() 84 | { 85 | HANDLE hProcess = NULL; 86 | PROCESS_INFORMATION pi; 87 | char parentPath[_MAX_PATH] = "\0"; 88 | if (!get_parent(&pi)) { 89 | error("Could not get parent process."); 90 | return false; 91 | } 92 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pi.dwProcessId); 93 | if( !hProcess ) { 94 | error("Couldn't open parent process.\n"); 95 | return false; 96 | } 97 | GetModuleFileNameA(NULL, thisPath, _MAX_PATH); 98 | GetModuleFileNameExA(hProcess, 0, parentPath, _MAX_PATH); 99 | if (_stricmp(parentPath, thisPath) == 0) { 100 | debug("Eliminating recursion.."); 101 | return false; 102 | } 103 | CloseHandle(hProcess); 104 | return true; 105 | } 106 | 107 | int main(int argc, char* argv[]) 108 | { 109 | size_t output_length; 110 | size_t input_length; 111 | HRSRC hrsrc; 112 | HGLOBAL hglb; 113 | LPBYTE bindata; 114 | FILE* fwork; 115 | const char* input; 116 | char* output; 117 | char tmpbuff[_MAX_PATH] = "\0"; 118 | char* substr = NULL; 119 | DWORD tmpbufflen = _MAX_PATH; 120 | int result = EXIT_SUCCESS; 121 | bool execLocal = false; 122 | #ifndef NO_COMPRESSION 123 | snappy_status status; 124 | #endif 125 | 126 | if(!eliminate_recursion()) 127 | return EXIT_FAILURE; 128 | 129 | hrsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_EXECLOCAL_FLAG), "FLAGS"); 130 | if (hrsrc && (hglb = LoadResource(NULL, hrsrc))) { 131 | bindata = (LPBYTE)LockResource(hglb); 132 | if(((char*)bindata)[0] == '1') execLocal = true; 133 | } 134 | 135 | hrsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_DEFAULT_EXEC), "EXEC"); 136 | if (hrsrc && (hglb = LoadResource(NULL, hrsrc))) { 137 | bindata = (LPBYTE)LockResource(hglb); 138 | input_length = (size_t)SizeofResource(NULL, hrsrc); 139 | input = (const char*)malloc(sizeof(const char) * input_length); 140 | if(input == NULL) { 141 | fatal("Could not allocate buffer for compressed data."); 142 | } 143 | memcpy((void*)input, (const void*)bindata, input_length); 144 | } else { 145 | fatal("Could not find and load packaged data."); 146 | } 147 | 148 | #ifndef NO_COMPRESSION 149 | if ((status = snappy_uncompressed_length(input, input_length, &output_length)) != SNAPPY_OK) { 150 | if(status == SNAPPY_INVALID_INPUT) { 151 | error("Invalid input."); 152 | } else if(status == SNAPPY_BUFFER_TOO_SMALL) { 153 | error("Buffer too small."); 154 | } 155 | free((void*)input); 156 | fatal("Could not find length of uncompressed data."); 157 | } 158 | 159 | output = (char*)malloc(output_length); 160 | if(output == NULL) { 161 | free((void*)input); 162 | fatal("Could not allocate buffer for uncompressed data."); 163 | } 164 | 165 | if ((status = snappy_uncompress((const char*)input, input_length, output, &output_length)) != SNAPPY_OK) { 166 | if(status == SNAPPY_INVALID_INPUT) { 167 | error("Invalid input."); 168 | } else if(status == SNAPPY_BUFFER_TOO_SMALL) { 169 | error("Buffer too small."); 170 | } 171 | error("Could not uncompress packaged data."); 172 | goto exception; 173 | } 174 | #else 175 | output = (char*)input; 176 | output_length = input_length; 177 | #endif 178 | 179 | if(execLocal) { 180 | strcpy(tmpbuff, thisPath); 181 | substr = strrchr((const char*)tmpbuff, '\\'); 182 | while(*(substr++) != '\0') 183 | *(substr) = '\0'; 184 | } else { 185 | if(!GetTempPathA(tmpbufflen, tmpbuff)) { 186 | error("Could not get temporary folder."); 187 | goto exception; 188 | } 189 | } 190 | 191 | srand(((unsigned int)time(NULL)) | 1); 192 | sprintf(tmpbuff, "%s%i.bat", tmpbuff, rand() % 10 + 1); 193 | 194 | debug("Writing temporary file to %s..", tmpbuff); 195 | if((fwork = fopen(tmpbuff, "wb")) == NULL) { 196 | error("Could not open temporary file."); 197 | goto exception; 198 | } 199 | 200 | if(!fwrite((const void*)output, sizeof(char), output_length / sizeof(char), fwork)) { 201 | fclose(fwork); 202 | error("Failed to write to temporary file."); 203 | goto exception; 204 | } 205 | fclose(fwork); 206 | argv[0] = tmpbuff; 207 | result = _spawnv(_P_WAIT, (const char*)tmpbuff, (const char* const*)argv); 208 | if(_access(tmpbuff, 00) == 0) _unlink(tmpbuff); 209 | 210 | goto finally; 211 | exception: 212 | result = EXIT_FAILURE; 213 | goto finally; 214 | finally: 215 | #ifndef NO_COMPRESSION 216 | free(output); 217 | #endif 218 | free((void*)input); 219 | return result; 220 | } 221 | -------------------------------------------------------------------------------- /include/snappy.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005 and onwards Google Inc. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // A light-weight compression algorithm. It is designed for speed of 30 | // compression and decompression, rather than for the utmost in space 31 | // savings. 32 | // 33 | // For getting better compression ratios when you are compressing data 34 | // with long repeated sequences or compressing data that is similar to 35 | // other data, while still compressing fast, you might look at first 36 | // using BMDiff and then compressing the output of BMDiff with 37 | // Snappy. 38 | 39 | #ifndef UTIL_SNAPPY_SNAPPY_H__ 40 | #define UTIL_SNAPPY_SNAPPY_H__ 41 | 42 | #include 43 | #include 44 | 45 | #include "snappy-stubs-public.h" 46 | 47 | namespace snappy { 48 | class Source; 49 | class Sink; 50 | 51 | // ------------------------------------------------------------------------ 52 | // Generic compression/decompression routines. 53 | // ------------------------------------------------------------------------ 54 | 55 | // Compress the bytes read from "*source" and append to "*sink". Return the 56 | // number of bytes written. 57 | size_t Compress(Source* source, Sink* sink); 58 | 59 | bool GetUncompressedLength(Source* source, uint32* result); 60 | 61 | // ------------------------------------------------------------------------ 62 | // Higher-level string based routines (should be sufficient for most users) 63 | // ------------------------------------------------------------------------ 64 | 65 | // Sets "*output" to the compressed version of "input[0,input_length-1]". 66 | // Original contents of *output are lost. 67 | // 68 | // REQUIRES: "input[]" is not an alias of "*output". 69 | size_t Compress(const char* input, size_t input_length, string* output); 70 | 71 | // Decompresses "compressed[0,compressed_length-1]" to "*uncompressed". 72 | // Original contents of "*uncompressed" are lost. 73 | // 74 | // REQUIRES: "compressed[]" is not an alias of "*uncompressed". 75 | // 76 | // returns false if the message is corrupted and could not be decompressed 77 | bool Uncompress(const char* compressed, size_t compressed_length, 78 | string* uncompressed); 79 | 80 | 81 | // ------------------------------------------------------------------------ 82 | // Lower-level character array based routines. May be useful for 83 | // efficiency reasons in certain circumstances. 84 | // ------------------------------------------------------------------------ 85 | 86 | // REQUIRES: "compressed" must point to an area of memory that is at 87 | // least "MaxCompressedLength(input_length)" bytes in length. 88 | // 89 | // Takes the data stored in "input[0..input_length]" and stores 90 | // it in the array pointed to by "compressed". 91 | // 92 | // "*compressed_length" is set to the length of the compressed output. 93 | // 94 | // Example: 95 | // char* output = new char[snappy::MaxCompressedLength(input_length)]; 96 | // size_t output_length; 97 | // RawCompress(input, input_length, output, &output_length); 98 | // ... Process(output, output_length) ... 99 | // delete [] output; 100 | void RawCompress(const char* input, 101 | size_t input_length, 102 | char* compressed, 103 | size_t* compressed_length); 104 | 105 | // Given data in "compressed[0..compressed_length-1]" generated by 106 | // calling the Snappy::Compress routine, this routine 107 | // stores the uncompressed data to 108 | // uncompressed[0..GetUncompressedLength(compressed)-1] 109 | // returns false if the message is corrupted and could not be decrypted 110 | bool RawUncompress(const char* compressed, size_t compressed_length, 111 | char* uncompressed); 112 | 113 | // Given data from the byte source 'compressed' generated by calling 114 | // the Snappy::Compress routine, this routine stores the uncompressed 115 | // data to 116 | // uncompressed[0..GetUncompressedLength(compressed,compressed_length)-1] 117 | // returns false if the message is corrupted and could not be decrypted 118 | bool RawUncompress(Source* compressed, char* uncompressed); 119 | 120 | // Returns the maximal size of the compressed representation of 121 | // input data that is "source_bytes" bytes in length; 122 | size_t MaxCompressedLength(size_t source_bytes); 123 | 124 | // REQUIRES: "compressed[]" was produced by RawCompress() or Compress() 125 | // Returns true and stores the length of the uncompressed data in 126 | // *result normally. Returns false on parsing error. 127 | // This operation takes O(1) time. 128 | bool GetUncompressedLength(const char* compressed, size_t compressed_length, 129 | size_t* result); 130 | 131 | // Returns true iff the contents of "compressed[]" can be uncompressed 132 | // successfully. Does not return the uncompressed data. Takes 133 | // time proportional to compressed_length, but is usually at least 134 | // a factor of four faster than actual decompression. 135 | bool IsValidCompressedBuffer(const char* compressed, 136 | size_t compressed_length); 137 | 138 | // *** DO NOT CHANGE THE VALUE OF kBlockSize *** 139 | // 140 | // New Compression code chops up the input into blocks of at most 141 | // the following size. This ensures that back-references in the 142 | // output never cross kBlockSize block boundaries. This can be 143 | // helpful in implementing blocked decompression. However the 144 | // decompression code should not rely on this guarantee since older 145 | // compression code may not obey it. 146 | static const int kBlockLog = 15; 147 | static const int kBlockSize = 1 << kBlockLog; 148 | 149 | static const int kMaxHashTableBits = 14; 150 | static const int kMaxHashTableSize = 1 << kMaxHashTableBits; 151 | 152 | } // end namespace snappy 153 | 154 | 155 | #endif // UTIL_SNAPPY_SNAPPY_H__ 156 | --------------------------------------------------------------------------------