X Tutup
#include "stdafx.h" #include "FileAttributes.h" #include #include //#include //for cout using namespace std; //****************************************************************************** //** FileAttributes Class //****************************************************************************** /** * JNI code used to list files, network drives, and file attributes on Windows * file systems. Requires "mpr.lib" and "Netapi32.lib" for network IO. * ******************************************************************************/ std::istringstream &operator >>(std::istringstream &iss, __int64 &n){ sscanf(iss.str().c_str(), "%I64d", &n); return iss; } //************************************************************************** //** from_string //************************************************************************** /** Allows users to append/concat an __int64 to a stringstream. This method * is required for Visual Studio 6 compilers. Visual Studio 2003 and higher * don't need this. GCC doesn't seem to need it either. Credit: * http://www.codeguru.com/forum/archive/index.php/t-342716.html */ template bool from_string(T &t, const std::string &s, std::ios_base & (*f)(std::ios_base&)){ std::istringstream iss(s); iss >> f, iss >> t; return !iss.fail(); } //************************************************************************** //** date2int //************************************************************************** /** Converts FILETIME to a long value representing a date. */ __int64 date2int(const FILETIME &ft){ SYSTEMTIME stUTC, stLocal; // Convert the last-write time to local time. FileTimeToSystemTime(&ft, &stUTC); SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); stringstream ss; ss << stLocal.wYear; if (stLocal.wMonth<10) ss << "0" << stLocal.wMonth; else ss << stLocal.wMonth; if (stLocal.wDay<10) ss << "0" << stLocal.wDay; else ss << stLocal.wDay; if (stLocal.wHour<10) ss << "0" << stLocal.wHour; else ss << stLocal.wHour; if (stLocal.wMinute<10) ss << "0" << stLocal.wMinute; else ss << stLocal.wMinute; if (stLocal.wSecond<10) ss << "0" << stLocal.wSecond; else ss << stLocal.wSecond; if (stLocal.wMilliseconds<100 && stLocal.wMilliseconds>10) ss << "0" << stLocal.wMilliseconds; else if (stLocal.wMilliseconds<10) ss << "00" << stLocal.wMilliseconds; else ss << stLocal.wMilliseconds; //cout << ss.str(); //cout << "\n"; __int64 val; bool bconvert = from_string<__int64>(val, ss.str(), std::dec); //ss >> val; return val; } //************************************************************************** //** GetFileAttributesEx //************************************************************************** /** Returns an array of long values representing WIN32_FILE_ATTRIBUTE_DATA. * Credit: http://www.cplusplus.com/forum/windows/24603/ * * Class: javaxt_io_File * Method: GetFileAttributesEx * Signature: (Ljava/lang/String;)[J */ JNIEXPORT jlongArray JNICALL Java_javaxt_io_File_GetFileAttributesEx(JNIEnv *env, jclass, jstring filename) { //Convert jstring to wstring const jchar *_filename = env->GetStringChars(filename, 0); jsize len = env->GetStringLength(filename); wstring path; path.assign(_filename, _filename + len); env->ReleaseStringChars(filename, _filename); //Get attributes WIN32_FILE_ATTRIBUTE_DATA fileAttrs; BOOL result = GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &fileAttrs); if (!result) { jclass exceptionClass = env->FindClass("java/lang/Exception"); env->ThrowNew(exceptionClass, "Exception Occurred"); } /* typedef struct _WIN32_FILE_ATTRIBUTE_DATA { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; */ //Create an array to store the WIN32_FILE_ATTRIBUTE_DATA jlong buffer[6]; buffer[0] = fileAttrs.dwFileAttributes; buffer[1] = date2int(fileAttrs.ftCreationTime); buffer[2] = date2int(fileAttrs.ftLastAccessTime); buffer[3] = date2int(fileAttrs.ftLastWriteTime); buffer[4] = fileAttrs.nFileSizeHigh; buffer[5] = fileAttrs.nFileSizeLow; jlongArray jLongArray = env->NewLongArray(6); env->SetLongArrayRegion(jLongArray, 0, 6, buffer); return jLongArray; } //************************************************************************** //** GetTarget //************************************************************************** /** Returns the target of a WIndows Junction. Credit: * http://www.flexhex.com/docs/articles/hard-links.phtml * * Class: javaxt_io_File * Method: GetTarget * Signature: (Ljava/lang/String;ZI)J */ JNIEXPORT jstring JNICALL Java_javaxt_io_File_GetTarget(JNIEnv *env, jclass, jstring filename) { //Convert jstring to wstring const jchar *_filename = env->GetStringChars(filename, 0); jsize len = env->GetStringLength(filename); wstring path; path.assign(_filename, _filename + len); env->ReleaseStringChars(filename, _filename); LPCWSTR pPath = GetTarget(path.c_str()); if (pPath==NULL) return NULL; else{ jchar * jc = (jchar *) pPath; int i = wcslen(pPath); return env->NewString(jc, i); } } //************************************************************************** //** GetSharedDrives - Requires Netapi32.lib //************************************************************************** /** Returns a list of shared drives found on a server * * Class: javaxt_io_File * Method: GetSharedDrives * Signature: (Ljava/lang/String;ZI)J */ JNIEXPORT jstring JNICALL Java_javaxt_io_File_GetSharedDrives(JNIEnv *env, jclass, jstring servername) { //Convert jstring to wstring const jchar *_servername = env->GetStringChars(servername, 0); jsize x = env->GetStringLength(servername); wstring str; str.assign(_servername, _servername + x); env->ReleaseStringChars(servername, _servername); wstringstream ss; PSHARE_INFO_502 BufPtr,p; NET_API_STATUS res; DWORD er=0,tr=0,resume=0, i; do{ res = NetShareEnum ((LPWSTR) str.c_str(), 502, (LPBYTE *) &BufPtr, MAX_PREFERRED_LENGTH, &er, &tr, &resume); if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA){ p=BufPtr; //Loop through the entries for (i=1; i<=er; i++) { //Iterate through the file changes wstring type = L"Unknown"; bool ret = true; switch(p->shi502_type){ case STYPE_DISKTREE: type = L"Disk"; break; case STYPE_PRINTQ: type = L"Printer"; ret = false; break; case STYPE_DEVICE: type = L"Device"; ret = false; break; case STYPE_IPC: type = L"IPC"; ret = false; break; //The following 2 lines won't compile on my Windows XP x32 //case STYPE_SPECIAL: type = L"Special"; break; //case STYPE_TEMPORARY: type = L"Temp"; break; } wstring path = wstring(p->shi502_path); if (path.empty()) ret = false; if (ret) ss << wstring(p->shi502_netname) << L"\t" << type << L"\t" << path << L"\n"; //if (IsValidSecurityDescriptor(p->shi502_security_descriptor)) // printf("Yes\n"); //else // printf("No\n"); p++; } //Free the allocated buffer NetApiBufferFree(BufPtr); } else { stringstream ss; ss << res; jclass exceptionClass = env->FindClass("java/lang/Exception"); env->ThrowNew(exceptionClass, ss.str().c_str()); } } while (res==ERROR_MORE_DATA); wstring cstr = ss.str(); int len = cstr.size(); jchar* raw = new jchar[len]; memcpy(raw, cstr.c_str(), len*sizeof(wchar_t)); jstring result = env->NewString(raw, len); delete[] raw; return result; } //************************************************************************** //** GetNetworkDrives //************************************************************************** /** Returns a list of network drives mounted on the host computer. This is * similar to the "net use" command. * * Class: javaxt_io_File * Method: GetNetworkDrives * Signature: (Ljava/lang/String;ZI)J */ JNIEXPORT jstring JNICALL Java_javaxt_io_File_GetNetworkDrives(JNIEnv *env, jclass) { wstringstream ss; HANDLE h; if (WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, RESOURCEUSAGE_ALL, NULL, &h) == NO_ERROR) { DWORD is = 2; NETRESOURCE buf[26] = { 0 }; DWORD c = -1; DWORD s = sizeof(buf); DWORD r; if ((r = WNetEnumResource(h, &c, buf, &s)) != NO_ERROR){ jclass exceptionClass = env->FindClass("java/lang/Exception"); env->ThrowNew(exceptionClass, "Exception Occurred"); } for (int i = 0; i < c; ++i){ NETRESOURCE ns = buf[i]; ss << ns.lpLocalName << L"\t" << ns.lpRemoteName << L"\n"; } } wstring cstr = ss.str(); int len = cstr.size(); jchar* raw = new jchar[len]; memcpy(raw, cstr.c_str(), len*sizeof(wchar_t)); jstring result = env->NewString(raw, len); delete[] raw; return result; } //************************************************************************** //** GetFiles //************************************************************************** /** Returns a list of files found in the current directory. Note that the * filename must end with "\*" * * Class: javaxt_io_File * Method: GetFiles * Signature: (Ljava/lang/String;ZI)J */ JNIEXPORT jstring JNICALL Java_javaxt_io_File_GetFiles(JNIEnv *env, jclass, jstring directory) { HANDLE hFind; try { //Convert jstring to wstring const jchar *_directory = env->GetStringChars(directory, 0); jsize x = env->GetStringLength(directory); wstring path; //L"C:\\temp\\*"; //Prepend "\\?\" path.assign(_directory, _directory + x); env->ReleaseStringChars(directory, _directory); if (x<2){ jclass exceptionClass = env->FindClass("java/lang/Exception"); env->ThrowNew(exceptionClass, "Invalid path, less than 2 characters long."); } /* int pos = path.find_last_of(L'\\'); int size = path.size(); if (pos != size - 1) { throw std::exception("CUtils::TraverseFS no trailing slash after path"); } */ wstringstream ss; BOOL bContinue = TRUE; WIN32_FIND_DATAW data; hFind = FindFirstFileW(path.c_str(), &data); if (INVALID_HANDLE_VALUE == hFind){ jclass exceptionClass = env->FindClass("java/lang/Exception"); env->ThrowNew(exceptionClass, "FindFirstFileW returned invalid handle."); } //HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //DWORD dwBytesWritten; // If we have no error, loop thru the files in this dir while (hFind && bContinue){ /* //Debug Print Statment. DO NOT DELETE! cout and wcout do not print unicode correctly. WriteConsole(hStdOut, data.cFileName, (DWORD)_tcslen(data.cFileName), &dwBytesWritten, NULL); WriteConsole(hStdOut, L"\n", 1, &dwBytesWritten, NULL); */ //Check if this entry is a directory if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ // Make sure this dir is not . or .. if (wstring(data.cFileName) != L"." && wstring(data.cFileName) != L"..") { ss << wstring(data.cFileName) << L"\\" << L"\n"; } } else{ ss << wstring(data.cFileName) << L"\n"; } bContinue = FindNextFileW(hFind, &data); } FindClose(hFind); // Free the dir structure wstring cstr = ss.str(); int len = cstr.size(); //WriteConsole(hStdOut, cstr.c_str(), len, &dwBytesWritten, NULL); //WriteConsole(hStdOut, L"\n", 1, &dwBytesWritten, NULL); jchar* raw = new jchar[len]; memcpy(raw, cstr.c_str(), len*sizeof(wchar_t)); jstring result = env->NewString(raw, len); delete[] raw; return result; } catch(...){ FindClose(hFind); jclass exceptionClass = env->FindClass("java/lang/Exception"); env->ThrowNew(exceptionClass, "Exception occured."); } return NULL; } /* //Code used to return a list of drives. Does not include disconnected network drives... DWORD dwLogicalDrives = GetLogicalDrives(); UINT nDrive = 0; for ( nDrive = 0; nDrive<32; nDrive++ ){ if ( dwLogicalDrives & (1 << nDrive) ){ wchar_t arr[] = { nDrive+'A', ':', '\\' }; wstring drive; drive.assign(arr, arr + 3); UINT uType = GetDriveTypeW(drive.c_str()); wstring type = L""; switch(uType){ case DRIVE_REMOVABLE: type = L"FLOPPY"; break; case DRIVE_FIXED: type = L"FIXED"; break; case DRIVE_REMOTE: type = L"NETWORK"; break; case DRIVE_CDROM: type = L"CDROM"; break; case DRIVE_RAMDISK: type = L"RAMDISK"; break; } ss << drive << L"\t" << type << L"\n"; } } */
X Tutup