/** * Loads the JVM. Every time this method is invoked, it attempts to create * a new JavaVM context. */ JavaVM * JVM_Create(JVM * jvm, int argc, Str args[]) { static Str szCreateVM = "JNI_CreateJavaVM"; /* load the JVM library */ if (!jvm->hModule) { jvm->hModule = LoadLibrary(jvm->javaLib); if (jvm->hModule) { FARPROC proc = GetProcAddress(jvm->hModule,szCreateVM); if (proc) { jvm->createVM = (CreateJavaVM)proc; } else { Error("ERROR: %s not found in %s\n",szCreateVM,jvm->javaLib); FreeLibrary(jvm->hModule); jvm->hModule = NULL; } } } /* create new VM */ if (jvm->createVM) { JavaVMInitArgs vm_args; memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_2; vm_args.ignoreUnrecognized = JNI_TRUE; vm_args.nOptions = argc; if (argc) { vm_args.options = MEM_NewArray(JavaVMOption,argc); if (vm_args.options) { int i; for (i=0; i<vm_args.nOptions; i++) { JavaVMOption * option = vm_args.options + i; memset(option, 0, sizeof(*option)); option->optionString = (char*)args[i]; } } } if (!argc || vm_args.options) { __try { JNIEnv * env = NULL; JavaVM * vm = NULL; int status = jvm->createVM(&vm, (void**)&env, &vm_args); ASSERT(status >= 0); if (status >= 0) { MEM_Free(vm_args.options); return vm; } } __except(EXCEPTION_EXECUTE_HANDLER) { ASSMSG2("EXCEPTION %08lX in %s",GetExceptionCode(),szCreateVM); } MEM_Free(vm_args.options); }
/** * Translates a binary buffer into a BASE64 encoded string using the specified * character to value mapping. The returned string is guaranteed to be a 7-bit * ASCII string. If buffer is empty, returns an empty string. Only returns NULL * if memory allocation fails. The caller will have to deallocate the returned * string with MEM_Free */ Char * BASE64_Encode(const void * data, size_t n, int flags) { const char* encodeMap = ((flags & BASE64_URLSAFE) ? base64_safeEncodeMap : base64_encodeMap); size_t alloc = ((n+2)/3)*4 + 1; Char * dest = MEM_NewArray(Char, alloc); if (dest) { const char * buf = (const char *)data; Char * p = dest; size_t off; /* encode the bulk of the data */ for (off=0; (off+3)<=n; off+=3) { *p++ = encodeMap[BASE64_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_3(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_4(buf,off)]; } /* manage the last few bytes */ switch (n%3) { case 0: break; case 1: *p++ = encodeMap[BASE64_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_2_1(buf,off)]; if (flags & BASE64_PAD) { *p++ = '='; *p++ = '='; } break; case 2: *p++ = encodeMap[BASE64_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_3_1(buf,off)]; if (flags & BASE64_PAD) *p++ = '='; break; } /* null terminate the destination string */ *p = 0; ASSERT(StrLen(dest) < (size_t)alloc); } return dest; }
/** * Returns pointer to buffer containing directory part of the given path. * The returned string is either empty or ends with file separator character. * Under Win32, if may also look like "C:", but in either case file name * can be simply appended to it. The return buffer has 'extra' additional * characters allocated past the end of the string. The function only * returns NULL if input parameter is NULL or memory allocation fails. */ Char * FILE_DirName(Str path, int extra) { Char * dir = NULL; ASSERT(path); ASSERT(extra >= 0); if (path) { size_t len = FILE_FilePart(path) - path; size_t size = len + 1; if (extra >= 0) size += extra; dir = MEM_NewArray(Char,size); /* copy portion of the source path */ if (dir) { if (len > 0) StrnCpy(dir, path, len); dir[len] = 0; } } return dir; }
/****************************************************************************\ * * NT_AllocUnicodeString() * * DESCRIPTION: * * Allocates an empty UNICODE string * * ARGUMENTS: * * MaxLen - max length of the string, in characters * * RETURN VALUE: * * Pointer to the allocated string, NULL if the allocation failed * \****************************************************************************/ PUNICODE_STRING NT_AllocUnicodeString (IN USHORT MaxLen) { PUNICODE_STRING String = NULL; ASSERT(MaxLen); if (MaxLen) { USHORT MaxByteLen = MaxLen*sizeof(WCHAR); USHORT NumBytes = (USHORT)(sizeof (UNICODE_STRING) + MaxByteLen); PUCHAR BytePtr = MEM_NewArray(UCHAR,NumBytes); if (BytePtr) { String = (PUNICODE_STRING)BytePtr; BytePtr += sizeof (UNICODE_STRING); RtlZeroMemory(String, sizeof (UNICODE_STRING) + sizeof(WCHAR)); String->MaximumLength = MaxByteLen; String->Buffer = (PWSTR)BytePtr; } } return (String); }
/** * UCS2_New - allocates a new uninitialized UCS2 string */ Ucs2 * UCS2_New(int len) { Ucs2 * str = MEM_NewArray(Ucs2,len+1); if (str) str[0] = 0; return str; }
/** * Translates binary data into a BASE32 encoded string. The returned string * is guaranteed to be a 7-bit ASCII string. If buffer is empty, returns an * empty string. Only returns NULL if memory allocation fails. The caller will * have to deallocate the returned string with MEM_Free */ Char* BASE32_Encode(const void * data, int n, int flags) { const char* encodeMap = ((flags & BASE32_LOWERCASE) ? base32_lowerCaseEncodeMap : base32_upperCaseEncodeMap); int alloc = (n/ENCODE_CHUNK_SIZE+((n%ENCODE_CHUNK_SIZE)?1:0))* DECODE_CHUNK_SIZE+1; /* * +--- octet 0 ---+--- octet 1 ---+--- octet 2 ---+ * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| * +---------+-----+---+---------+-+-------+-------+ * |4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 * +-0.index-+-1.index-+-2.index-+-3.index-+-4.index * * +--- octet 3 ---+--- octet 4 ---+ * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| * +-+---------+---+-----+---------+ * 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0| * --+-5.index-+-6.index-+-7.index-+ */ Char * dest = MEM_NewArray(Char, alloc); if (dest) { const char * buf = (const char *)data; Char* p = dest; int off; /* encode the bulk of the data */ for (off=0; (off+ENCODE_CHUNK_SIZE)<=n; off+=ENCODE_CHUNK_SIZE) { *p++ = encodeMap[BASE32_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_3(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_4(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_5(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_6(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_7(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_8(buf,off)]; } /* manage the last few bytes */ switch (n % ENCODE_CHUNK_SIZE) { case 0: break; case 1: *p++ = encodeMap[BASE32_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_2_1(buf,off)]; break; case 2: *p++ = encodeMap[BASE32_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_3(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_4_1(buf,off)]; break; case 3: *p++ = encodeMap[BASE32_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_3(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_4(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_5_1(buf,off)]; break; case 4: *p++ = encodeMap[BASE32_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_3(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_4(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_5(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_6(buf,off)]; *p++ = encodeMap[BASE32_ENCODE_7_1(buf,off)]; break; } /* append padding characters */ if (flags & BASE32_PAD) { Str pad = base32_pad[n % ENCODE_CHUNK_SIZE]; while (*pad) *p++ = *pad++; } /* null terminate the destination string */ *p = 0; ASSERT(StrLen(dest) < (size_t)alloc); } return dest; }
/** * Same as the above, only allows you to specify file mode (text vs binary) * on those platforms where it matters (e.g. Windows). */ Bool FILE_Save2(Str fname, FileSaveCB cb, void * ctx, Bool txt, IODesc io) { Bool success = False; ASSERT(fname && fname[0]); if (fname && fname[0]) { Char * tmp1 = FILE_DirName(fname, TEMP_FILE_NAME_LEN); if (tmp1 && (!tmp1[0] || FILE_MkDir(tmp1))) { const char * mode = txt ? WRITE_TEXT_MODE : WRITE_BINARY_MODE; size_t dirlen = StrLen(tmp1); File * f; /* * write the temp file */ FILE_MakeUnique(tmp1, dirlen, TEMP_FILE_NAME_LEN); f = FILE_Open(tmp1, mode, io); if (f) { Bool saved = (*cb)(f,fname,ctx); FILE_Close(f); if (saved) { if (FILE_CanRead(fname)) { /* * generate another unique file name */ size_t nchars = dirlen + 1 + TEMP_FILE_NAME_LEN; Char * tmp2 = MEM_NewArray(Char,nchars); if (tmp2) { StrCpy(tmp2, tmp1); FILE_MakeUnique(tmp2,dirlen,TEMP_FILE_NAME_LEN); /* * rename target -> tmp2 */ Verbose(TEXT("Renaming %s into %s\n"),fname,tmp2); if (FILE_Rename(fname, tmp2)) { /* * rename tmp1 -> target */ Verbose(TEXT("Renaming %s into %s\n"),tmp1,fname); if (FILE_Rename(tmp1, fname)) { /* * finally, remove tmp2 (old target) * perhaps, we should ignore the error * returned by FILE_Delete? */ Verbose(TEXT("Deleting %s\n"),tmp2); success = FILE_Delete(tmp2); } } MEM_Free(tmp2); } /* * there's no target, just rename tmp1 -> target */ } else { Verbose(TEXT("Renaming %s into %s\n"),tmp1,fname); success = FILE_Rename(tmp1, fname); } } else { /* * just quietly delete the temporary file. An error * message, if any, should have been provided by the * callback. */ FILE_Delete(tmp1); } } } MEM_Free(tmp1); } return success; }