/** * returns a handle to a file list. This handle can be used in * subsequent calls to javacall_dir_get_next() to iterate through * the file list and get the names of files that match the given string. * * @param path the name of a directory, but it can be a * partial file name * @param pathLen length of directory name * @return pointer to an opaque filelist structure, that can be used in * javacall_dir_get_next() and javacall_dir_close * NULL returned on error, for example if root directory of the * input 'string' cannot be found. */ javacall_handle javacall_dir_open(const javacall_utf16* path, int pathLen) { javacall_handle handle; wchar_t wOsPath[JAVACALL_MAX_FILE_NAME_LENGTH]; // max file name if( pathLen > JAVACALL_MAX_FILE_NAME_LENGTH ) { javacall_print("javacall_dir_open: Path length too long"); return NULL; } memset(wOsPath, 0, JAVACALL_MAX_FILE_NAME_LENGTH*sizeof(wchar_t)); memcpy(wOsPath, path, pathLen*sizeof(wchar_t)); wOsPath[pathLen++] = javacall_get_file_separator(); wOsPath[pathLen++] = '*'; // DEBUG printf("dir open: (%ws) \n", wOsPath); handle = FindFirstFileW(wOsPath, &javacall_dir_data); if (handle == INVALID_HANDLE_VALUE) { return NULL; } javacall_dir_first_time = TRUE; return handle; }
/** * Returns the localized names for mounted root file systems (UNICODE format) * @param roots buffer to store the UNICODE string containing localized names * of currently mounted roots separated by ';' character * @param rootsLen available buffer size (maximum number of javacall_utf16 * symbols to be stored) * @return <tt>JAVACALL_OK</tt> on success, * <tt>JAVACALL_FAIL</tt> otherwise */ javacall_result javacall_fileconnection_get_localized_mounted_roots(javacall_utf16* /* OUT */ roots, int rootsLen) { unsigned long driveMask; unsigned short ch = 'A'; int index = 0; for(driveMask = _getdrives(); driveMask; driveMask >>= 1) { if(driveMask & 1) { if(index > 0 && index > rootsLen - 5 - (int)(sizeof(localized_root_prefix) / sizeof(javacall_utf16) - 1) || rootsLen < 4 + (sizeof(localized_root_prefix) / sizeof(javacall_utf16) - 1)) { javacall_print("Error: javacall_fileconnection_get_localized_mounted_roots(), buffer is too small\n"); return JAVACALL_FAIL; } if(index > 0) { roots[index++] = ';'; } memcpy(roots + index, localized_root_prefix, sizeof(localized_root_prefix)); index += sizeof(localized_root_prefix) / sizeof(javacall_utf16) - 1; roots[index++] = ch; roots[index++] = ':'; roots[index++] = javacall_get_file_separator(); } ch++; } roots[index] = 0; return JAVACALL_OK; }
/** * Returns OS-specific path for the specified file system root. * @param rootName Root name in UNICODE * @param rootNameLen length of rootName * @param pathName buffer to store the UNICODE string containing * the system-dependent path to access the specified * root * @param pathNameLen available buffer size (maximum number of javacall_utf16 * symbols to be stored) * @return <tt>JAVACALL_OK</tt> on success, * <tt>JAVACALL_FAIL</tt> otherwise */ javacall_result javacall_fileconnection_get_path_for_root(const javacall_utf16* rootName, int rootNameLen, javacall_utf16* /* OUT */ pathName, int pathNameLen) { if(pathNameLen < rootNameLen - PREFIX_CHARS + 1) { javacall_print("Error: javacall_fileconnection_get_path_for_root(), buffer is too small\n"); return JAVACALL_FAIL; } pathName[rootNameLen - PREFIX_CHARS] = 0; pathName[--rootNameLen - PREFIX_CHARS] = javacall_get_file_separator(); while(--rootNameLen >= PREFIX_CHARS) { pathName[rootNameLen - PREFIX_CHARS] = rootName[rootNameLen]; } return JAVACALL_OK; }
/** * Returns the root path of java's home directory. * * @param rootPath returned value: pointer to unicode buffer, allocated * by the VM, to be filled with the root path. * @param rootPathLen IN : lenght of max rootPath buffer * OUT : lenght of set rootPath * @return <tt>JAVACALL_OK</tt> if operation completed successfully * <tt>JAVACALL_FAIL</tt> if an error occured */ javacall_result javacall_dir_get_root_path(javacall_utf16* /* OUT */ rootPath, int* /*IN | OUT*/ rootPathLen) { wchar_t dirBuffer[JAVACALL_MAX_ROOT_PATH_LENGTH + 1]; wchar_t currDir[JAVACALL_MAX_ROOT_PATH_LENGTH + 1]; wchar_t* midpHome; if (rootPath == NULL || rootPathLen == NULL) { return JAVACALL_FAIL; } /* * If MIDP_HOME is set, just use it. Does not check if MIDP_HOME is * pointing to a directory contain "appdb". */ midpHome = _wgetenv(L"MIDP_HOME"); if (midpHome != NULL) { int len = (int) wcslen(midpHome); if (len >= *rootPathLen) { * rootPathLen = 0; javacall_print("javacall_dir_get_root_path: MIDP_HOME " "is too long."); return JAVACALL_FAIL; } wcscpy(rootPath, midpHome); * rootPathLen = len; return JAVACALL_OK; } /* * Look for "appdb" until it is found in the following places: * - current directory; * - the parent directory of the midp executable; * - the grandparent directory of the midp executable. */ if ( _wgetcwd( currDir, sizeof(currDir)/sizeof(wchar_t) ) == NULL) { * rootPathLen = 0; javacall_print("javacall_dir_get_root_path: _wgetcwd failed"); return JAVACALL_FAIL; } else { wchar_t* lastsep; struct _stat statbuf; int i, j = 1; wchar_t chSep = javacall_get_file_separator(); wchar_t filesep[2] = {chSep, (wchar_t)0}; dirBuffer[sizeof(dirBuffer)/sizeof(wchar_t) - 1] = (wchar_t)0; wcsncpy(dirBuffer, currDir, sizeof(dirBuffer)/sizeof(wchar_t) - 1); while (j < 2) { /* Look for the last slash in the pathname. */ lastsep = wcsrchr(dirBuffer, *filesep); if (lastsep != NULL) { *(lastsep + 1) = (wchar_t)'\0'; } else { /* no file separator */ wcscpy(dirBuffer, L"."); wcscat(dirBuffer, filesep); } wcscat(dirBuffer, L"appdb"); i = 0; /* try to search for "appdb" 3 times only (see above) */ while (i < 3) { memset(&statbuf, 0, sizeof(statbuf)); /* found it and it is a directory */ if ((_wstat(dirBuffer, &statbuf) == 0) && (statbuf.st_mode & S_IFDIR)) { break; } /* strip off "appdb" to add 1 more level of ".." */ *(wcsrchr(dirBuffer, *filesep)) = (wchar_t)'\0'; wcscat(dirBuffer, filesep); wcscat(dirBuffer, L".."); wcscat(dirBuffer, filesep); wcscat(dirBuffer, L"appdb"); i++; } /* end while (i < 3) */ if (i < 3) { break; } j++; } /* end while (j < 2) */ if (j == 2) { javacall_print("Warning: cannot find appdb subdirectory.\n" "Please specify MIDP_HOME environment variable such " "that $MIDP_HOME\\lib contains the proper configuration " "files.\n"); return JAVACALL_FAIL; } /* strip off "appdb" from the path */ *(wcsrchr(dirBuffer, *filesep)) = (wchar_t)'\0'; wcscpy(rootPath, dirBuffer); * rootPathLen = wcslen(rootPath); return JAVACALL_OK; } }
/** * Get size in bytes of all files and possibly subdirectories contained * in the specified dir. * * @param pathName path name in UNICODE of directory * @param pathNameLen length of path name * @param includeSubdirs if JAVACALL_TRUE include subdirectories size too, * if JAVACALL_FALSE do not include subdirectories * @param result returned value: size in bytes of all files contained in * the specified directory and possibly its subdirectories * @return <tt>JAVACALL_OK</tt> on success, * <tt>JAVACALL_FAIL</tt> otherwise */ javacall_result javacall_fileconnection_dir_content_size(const javacall_utf16* pathName, int pathNameLen, javacall_bool includeSubdirs, javacall_int64* /* OUT */ result) { wchar_t subSearch[JAVACALL_MAX_FILE_NAME_LENGTH + 3]; WIN32_FIND_DATAW dir_data; javacall_int64 contentSize = 0; HANDLE listHandle[MAX_DIRECTORY_NESTING_LEVEL]; int pathLen[MAX_DIRECTORY_NESTING_LEVEL]; int nestLevel = 0; int nextExists = 1; memcpy(subSearch, pathName, pathNameLen * sizeof(javacall_utf16)); subSearch[pathNameLen++] = javacall_get_file_separator(); subSearch[pathNameLen++] = '*'; subSearch[pathNameLen] = 0; listHandle[0] = FindFirstFileW(subSearch, &dir_data); pathLen[0] = pathNameLen - 1; if (INVALID_HANDLE_VALUE == listHandle[0]) { javacall_print("Error: javacall_fileconnection_dir_content_size(), cannot open directory\n"); return JAVACALL_FAIL; } for ( ; ; ) { while (nextExists) { if ((dir_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { // found subdirectory if (JAVACALL_TRUE == includeSubdirs) { // must count subdirectory sizes int dirNameLen = wcslen(dir_data.cFileName); if (wcscmp(dir_data.cFileName, L".") && wcscmp(dir_data.cFileName, L"..")) { // the subdirectory is not "." or ".." if (nestLevel >= MAX_DIRECTORY_NESTING_LEVEL - 1) { // nesting level overflow while (nestLevel >= 0) { FindClose(listHandle[nestLevel--]); } javacall_print("Error: javacall_fileconnection_dir_content_size(), directory nesting overflow\n"); return JAVACALL_FAIL; } subSearch[pathLen[nestLevel]] = 0; wcscat(subSearch, dir_data.cFileName); pathLen[nestLevel + 1] = pathLen[nestLevel] + dirNameLen; subSearch[pathLen[++nestLevel]++] = javacall_get_file_separator(); subSearch[pathLen[nestLevel]] = '*'; subSearch[pathLen[nestLevel] + 1] = 0; listHandle[nestLevel] = FindFirstFileW(subSearch, &dir_data); if (INVALID_HANDLE_VALUE == listHandle[nestLevel]) { while (--nestLevel >= 0) { FindClose(listHandle[nestLevel]); } javacall_print("Error: javacall_fileconnection_dir_content_size(), cannot open subdirectory\n"); return JAVACALL_FAIL; } nextExists = 1; continue; } } } else { contentSize += ((javacall_int64)(dir_data.nFileSizeHigh) << 32) + dir_data.nFileSizeLow; } nextExists = FindNextFileW(listHandle[nestLevel], &dir_data); } FindClose(listHandle[nestLevel]); if (nestLevel > 0) { nextExists = FindNextFileW(listHandle[--nestLevel], &dir_data); } else { break; } } *result = contentSize; return JAVACALL_OK; }
/** * This helper function deletes the specified directory and all * its contents. * * @param pDirName the directory to delete */ void do_cleanup(const pcsl_string* pDirName) { pcsl_string name1 = PCSL_STRING_NULL; pcsl_string * pSubDir = &name1; pcsl_string name2 = PCSL_STRING_NULL; pcsl_string * pDirEntry = &name2; pcsl_string * tmp; javacall_handle listHandle; int nestLevel = 0; int pathLen; javacall_utf16 * fileName = NULL; int fileNameLen = 0; pcsl_string_status status; javacall_result res; int finish = 0; jchar sep = javacall_get_file_separator(); // initialize current directory if (PCSL_STRING_OK != pcsl_string_dup(pDirName, pSubDir)) { return; } for ( ; ; ) { // open upper-level directory for listing GET_PCSL_STRING_DATA_AND_LENGTH(pSubDir) if (PCSL_STRING_PARAMETER_ERROR(pSubDir)) { listHandle = NULL; } else { listHandle = javacall_dir_open(pSubDir_data, pSubDir_len); } RELEASE_PCSL_STRING_DATA_AND_LENGTH if (NULL == listHandle) { pcsl_string_free(pSubDir); return; } // get the first entry in the current directory fileName = javacall_dir_get_next(listHandle, &fileNameLen); while (NULL != fileName) { // compose full path for the directory entry if (PCSL_STRING_OK != pcsl_string_dup(pSubDir, pDirEntry)) { javacall_dir_close(listHandle); pcsl_string_free(pSubDir); return; } pcsl_string_predict_size(pDirEntry, pcsl_string_length(pDirEntry) + 1 + fileNameLen); if (PCSL_STRING_OK != pcsl_string_append_char(pDirEntry, sep) || PCSL_STRING_OK != pcsl_string_append_buf(pDirEntry, fileName, fileNameLen)) { javacall_dir_close(listHandle); pcsl_string_free(pSubDir); pcsl_string_free(pDirEntry); return; } // check if directory entry is a subdirectory GET_PCSL_STRING_DATA_AND_LENGTH(pDirEntry) if (PCSL_STRING_PARAMETER_ERROR(pDirEntry)) { finish = 1; } else { res = javacall_fileconnection_dir_exists(pDirEntry_data, pDirEntry_len); } RELEASE_PCSL_STRING_DATA_AND_LENGTH if (finish) { javacall_dir_close(listHandle); pcsl_string_free(pSubDir); pcsl_string_free(pDirEntry); return; } if (JAVACALL_OK == res) { // found subdirectory, open it for listing javacall_dir_close(listHandle); pcsl_string_free(pSubDir); tmp = pDirEntry; pDirEntry = pSubDir; pSubDir = tmp; GET_PCSL_STRING_DATA_AND_LENGTH(pSubDir) if (PCSL_STRING_PARAMETER_ERROR(pSubDir)) { listHandle = NULL; } else { listHandle = javacall_dir_open(pSubDir_data, pSubDir_len); } RELEASE_PCSL_STRING_DATA_AND_LENGTH if (NULL == listHandle) { pcsl_string_free(pSubDir); return; } nestLevel++; } else { // found regular file, simply remove it GET_PCSL_STRING_DATA_AND_LENGTH(pDirEntry) if (PCSL_STRING_PARAMETER_ERROR(pDirEntry)) { res = JAVACALL_FAIL; } else { // ensure that the file is not read-only javacall_fileconnection_set_writable(pDirEntry_data, pDirEntry_len, JAVACALL_TRUE); res = javacall_file_delete(pDirEntry_data, pDirEntry_len); } RELEASE_PCSL_STRING_DATA_AND_LENGTH pcsl_string_free(pDirEntry); if (JAVACALL_OK != res) { javacall_dir_close(listHandle); pcsl_string_free(pSubDir); return; } } // iterate through the current directory fileName = javacall_dir_get_next(listHandle, &fileNameLen); }