bool sameVolume( const QString & p1, const QString &p2 ) { #ifdef Q_OS_WIN32 wchar_t s1[ 1000 ] = { 0 }, s2[ 1000 ] = { 0 }; wchar_t b1[ 100 ] = { 0 }, b2[ 100 ] = { 0 }; QDir::toNativeSeparators( p1 ).toWCharArray( s1 ); QDir::toNativeSeparators( p2 ).toWCharArray( s2 ); GetVolumePathName( s1, b1, 99 ); GetVolumePathName( s2, b2, 99 ); return QString::fromWCharArray( b1 ) == QString::fromWCharArray( b2 ); #else struct stat s1, s2; stat( p1.toAscii().data(), &s1 ); stat( p2.toAscii().data(), &s2 ); return s1.st_dev == s2.st_dev; #endif }
BOOL GetFileSystemType(const char *szFileName, enum EV_FileSystem *pFS) { char szFS[256]; char root[MAX_PATH]; *pFS = EV_FS_TYPE_RAW; if (!GetVolumePathName (szFileName, root, sizeof (root))) return FALSE; if ( GetVolumeInformation (root, NULL, 0, NULL, NULL, NULL, szFS, sizeof(szFS)) ) { if (!strncmp (szFS, "NTFS", 4)) *pFS = EV_FS_TYPE_NTFS; else if (!strncmp (szFS, "FAT", 3)) // FAT16, FAT32 *pFS = EV_FS_TYPE_FAT; else *pFS = EV_FS_TYPE_RAW; } else { return FALSE; } return TRUE; }
BOOL GetFileSystemType(const wchar_t *szFileName, enum EV_FileSystem *pFS) { wchar_t szFS[256]; wchar_t root[MAX_PATH]; *pFS = EV_FS_TYPE_RAW; if (!GetVolumePathName (szFileName, root, ARRAYSIZE (root))) return FALSE; if ( GetVolumeInformation (root, NULL, 0, NULL, NULL, NULL, szFS, ARRAYSIZE(szFS)) ) { if (!wcsncmp (szFS, L"NTFS", 4)) *pFS = EV_FS_TYPE_NTFS; else if (!wcsncmp (szFS, L"FAT", 3)) // FAT16, FAT32 *pFS = EV_FS_TYPE_FAT; else if (!_wcsnicmp (szFS, L"exFAT", 5)) // exFAT *pFS = EV_FS_TYPE_EXFAT; else *pFS = EV_FS_TYPE_RAW; } else { return FALSE; } return TRUE; }
int my_getvolumeinfo (const TCHAR *root) { DWORD v, err; int ret = 0; TCHAR volume[MAX_DPATH]; v = GetFileAttributesSafe (root); err = GetLastError (); if (v == INVALID_FILE_ATTRIBUTES) return -1; if (!(v & FILE_ATTRIBUTE_DIRECTORY)) return -2; /* if (v & FILE_ATTRIBUTE_READONLY) ret |= MYVOLUMEINFO_READONLY; */ if (GetVolumePathName (root, volume, sizeof (volume))) { TCHAR fsname[MAX_DPATH]; DWORD comlen; DWORD flags; if (GetVolumeInformation (volume, NULL, 0, NULL, &comlen, &flags, fsname, sizeof fsname / sizeof (TCHAR))) { //write_log (_T("Volume %s FS=%s maxlen=%d flags=%08X\n"), volume, fsname, comlen, flags); if (flags & FILE_NAMED_STREAMS) ret |= MYVOLUMEINFO_STREAMS; } } return ret; }
JSBool wimg_apply_image(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { DWORD applyFlags = 0; LPWSTR path = NULL; JS_BeginRequest(cx); if(!JS_ConvertArguments(cx, argc, argv, "W /u", &path, &applyFlags)) { JS_ReportError(cx, "Error during argument parsing in WIMApplyImage"); JS_EndRequest(cx); return JS_FALSE; } HANDLE imageHandle = JS_GetPrivate(cx, obj); jsrefcount rCount = JS_SuspendRequest(cx); *rval = WIMApplyImage(imageHandle, path, applyFlags) ? JSVAL_TRUE : JSVAL_FALSE; JS_ResumeRequest(cx, rCount); if(*rval == JSVAL_FALSE) { JS_EndRequest(cx); return JS_TRUE; } TCHAR volumeName[MAX_PATH + 1]; memset(volumeName, 0, sizeof(TCHAR) * (MAX_PATH + 1)); _tcscat_s(volumeName, MAX_PATH + 1, TEXT("\\\\.\\")); _tcscat_s(volumeName, (MAX_PATH + 1) - 4, path); if(!GetVolumePathName(volumeName, volumeName, MAX_PATH + 1)) { JS_EndRequest(cx); *rval = JSVAL_FALSE; return JS_TRUE; } LPTSTR lastSlash = _tcsrchr(volumeName, _T('\\')); *lastSlash = '\0'; HANDLE volumeHandle = CreateFile(volumeName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(volumeHandle == INVALID_HANDLE_VALUE) { JS_EndRequest(cx); *rval = JSVAL_FALSE; return JS_TRUE; } rCount = JS_SuspendRequest(cx); if(!FlushFileBuffers(volumeHandle)) { CloseHandle(volumeHandle); JS_ResumeRequest(cx, rCount); JS_EndRequest(cx); *rval = JSVAL_FALSE; return JS_TRUE; } CloseHandle(volumeHandle); JS_ResumeRequest(cx, rCount); *rval = JSVAL_TRUE; JS_EndRequest(cx); return JS_TRUE; }
/* QueryVolumeInfo Retrieves the free disk space and file size limit on the truecrypt volume host Parameters: hwndDlg : HWND [in] handle to parent window lpszVolume : char * [in] Pointer to a string that contains the volume path pHostSizeFree : uint64 * [out] returns the free space available on the host (always zero for devices) pSizeLimitFS : uint64 * [out] returns the file size limit of the host file system Return value: int with TrueCrypt error code (ERR_SUCCESS on success) */ int QueryVolumeInfo (HWND hwndDlg, const char *lpszVolume, uint64 * pHostSizeFree, uint64 * pSizeLimitFS ) { int nStatus = ERR_OS_ERROR; char szDiskFile[TC_MAX_PATH], root[MAX_PATH]; BOOL bDevice; enum EV_FileSystem fs; *pSizeLimitFS = (uint64)-1; CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), lpszVolume, &bDevice); if (bDevice) { *pHostSizeFree=0; return ERR_SUCCESS; } if (!GetVolumePathName (szDiskFile, root, sizeof (root))) { nStatus = ERR_OS_ERROR; goto error; } if( ! GetDiskFreeSpaceEx (root,(PULARGE_INTEGER)pHostSizeFree,NULL,NULL) ) { nStatus = ERR_OS_ERROR; goto error; } if ( ! GetFileSystemType(root,&fs) ) { nStatus = ERR_OS_ERROR; goto error; } /* file size limits FAT16 / FAT32 : 4 GB minus 1 byte (2^32 bytes minus 1 byte) NTFS : Architecturally : 16 exabytes minus 1 KB (26^4 bytes minus 1 KB) Implementation (Windows Server 2008): 16 terabytes minus 64 KB (2^44 bytes minus 64 KB) */ switch (fs) { case EV_FS_TYPE_NTFS: *pSizeLimitFS = 16 * BYTES_PER_TB - 64 * BYTES_PER_KB; break; case EV_FS_TYPE_FAT: *pSizeLimitFS = 4 * BYTES_PER_GB - 1; break; default: *pSizeLimitFS = (uint64)-1; } nStatus = ERR_SUCCESS; error: return nStatus; }
bool is_network_path(const std::wstring& path) { wchar_t buff[MAX_PATH]; return #if defined(ONECORE) PathIsUNCEx(path.c_str(), nullptr) #else PathIsUNC(path.c_str()) #endif || (GetVolumePathName(path.c_str(), buff, MAX_PATH) && GetDriveType(buff) == DRIVE_REMOTE); }
static char * get_root(void) { #ifndef _WIN32 return x_strdup("/"); #else char volume[4]; // "C:\" GetVolumePathName(get_cwd(), volume, sizeof(volume)); return x_strdup(volume); #endif }
bool IsOnFixedDrive(const WCHAR *path) { if (PathIsNetworkPath(path)) return false; UINT type; WCHAR root[MAX_PATH]; if (GetVolumePathName(path, root, dimof(root))) type = GetDriveType(root); else type = GetDriveType(path); return DRIVE_FIXED == type; }
/* * PrintDirectoryHeader * * print the header for the dir command */ static BOOL PrintDirectoryHeader(LPTSTR szPath, LPDIRSWITCHFLAGS lpFlags) { TCHAR szMsg[RC_STRING_MAX_SIZE]; TCHAR szFullDir[MAX_PATH]; TCHAR szRootName[MAX_PATH]; TCHAR szVolName[80]; LPTSTR pszFilePart; DWORD dwSerialNr; if (lpFlags->bBareFormat) return TRUE; if (GetFullPathName(szPath, sizeof(szFullDir) / sizeof(TCHAR), szFullDir, &pszFilePart) == 0) { ErrorMessage(GetLastError(), _T("Failed to build full directory path")); return FALSE; } if (pszFilePart != NULL) *pszFilePart = _T('\0'); /* get the media ID of the drive */ if (!GetVolumePathName(szFullDir, szRootName, sizeof(szRootName) / sizeof(TCHAR)) || !GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr, NULL, NULL, NULL, 0)) { return(TRUE); } /* print drive info */ if (szVolName[0] != _T('\0')) { LoadString(CMD_ModuleHandle, STRING_DIR_HELP2, szMsg, RC_STRING_MAX_SIZE); DirPrintf(lpFlags, szMsg, szRootName[0], szVolName); } else { LoadString(CMD_ModuleHandle, STRING_DIR_HELP3, szMsg, RC_STRING_MAX_SIZE); DirPrintf(lpFlags, szMsg, szRootName[0]); } /* print the volume serial number if the return was successful */ LoadString(CMD_ModuleHandle, STRING_DIR_HELP4, (LPTSTR) szMsg, RC_STRING_MAX_SIZE); DirPrintf(lpFlags, szMsg, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); return TRUE; }
STDMETHODIMP CAnalyzerWriterInput::GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES*pProps) { UNREFERENCED_PARAMETER(pProps); if (!pProps) return E_POINTER; pProps->cBuffers = 0; pProps->cbPrefix = 0; pProps->cbBuffer = 0; // Get Alignment LPTSTR lpRootPathName = NULL; if (m_pFile && m_pFile != INVALID_HANDLE_VALUE) { lpRootPathName = new TCHAR[MAX_PATH]; if (!GetVolumePathName(m_szFileName, lpRootPathName, MAX_PATH)) { delete[] lpRootPathName; lpRootPathName = NULL; } } DWORD dwSectorsPerCluster = 0; DWORD dwBytesPerSector = 0; DWORD dwNumberOfFreeClusters = 0; DWORD dwTotalNumberOfClusters = 0; if (!GetDiskFreeSpace(lpRootPathName, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters)) { DWORD error = GetLastError(); if (lpRootPathName) { delete[] lpRootPathName; lpRootPathName = NULL; } if (error != 0) return HRESULT_FROM_WIN32(error); } pProps->cbAlign = dwBytesPerSector; if (lpRootPathName) delete[] lpRootPathName; return S_OK; }
BOOL _GetDiskFreeSpaceEx( LPCTSTR lpDirectoryName, // ディレクトリ名 PULARGE_INTEGER lpFreeBytesAvailable, // 呼び出し側が利用できるバイト数 PULARGE_INTEGER lpTotalNumberOfBytes, // ディスク全体のバイト数 PULARGE_INTEGER lpTotalNumberOfFreeBytes // ディスク全体の空きバイト数 ) { TCHAR szVolumePathName[MAX_PATH] = _T(""); if( GetVolumePathName( lpDirectoryName, szVolumePathName, MAX_PATH) == FALSE ){ return GetDiskFreeSpaceEx( lpDirectoryName, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes ); } TCHAR szMount[MAX_PATH] = _T(""); if( GetVolumeNameForVolumeMountPoint(szVolumePathName, szMount, MAX_PATH) == FALSE ){ return GetDiskFreeSpaceEx( szVolumePathName, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes ); } return GetDiskFreeSpaceEx( szMount, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes ); }
static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_VOLUME_INFO *VolumeInfo) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR Root[MAX_PATH]; ULARGE_INTEGER TotalSize, FreeSize; if (!GetVolumePathName(Ptfs->Path, Root, MAX_PATH)) return FspNtStatusFromWin32(GetLastError()); if (!GetDiskFreeSpaceEx(Root, 0, &TotalSize, &FreeSize)) return FspNtStatusFromWin32(GetLastError()); VolumeInfo->TotalSize = TotalSize.QuadPart; VolumeInfo->FreeSize = FreeSize.QuadPart; return STATUS_SUCCESS; }
HRESULT pGetVolumeMountPointForPathW( __in LPCWSTR Path, __out LPWSTR* MountPoint) { if (NULL == MountPoint) { return E_POINTER; } *MountPoint = NULL; // TODO: It is possible to be the path is more than MAX_PATH // in case of supporting unicode file names up to 65534 DWORD mountPointLength = MAX_PATH; XTL::AutoProcessHeapPtr<TCHAR> mountPoint = static_cast<TCHAR*>( ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, mountPointLength * sizeof(WCHAR))); if (mountPoint.IsInvalid()) { return E_OUTOFMEMORY; } if (!GetVolumePathName(Path, mountPoint, mountPointLength)) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); XTLTRACE2(NdasVolTrace, TRACE_LEVEL_ERROR, "GetVolumePathName(%ls) failed, hr=0x%X\n", Path, hr); return hr; } XTLTRACE2(NdasVolTrace, TRACE_LEVEL_INFORMATION, "Path(%ls) is mounted from %s.\n", Path, mountPoint); *MountPoint = mountPoint.Detach(); return S_OK; }
bool WinReviveNetworkResource(uint16 * _wfileName) { bool result = false; HWND windowHandle = null; NETRESOURCE nr = { 0 }; nr.dwType = RESOURCETYPE_DISK; nr.lpRemoteName = _wfileName; if(_wfileName[0] != '\\' || _wfileName[1] == '\\') { uint16 volumePathName[MAX_LOCATION]; if(GetVolumePathName(_wfileName, volumePathName, MAX_LOCATION)) { uint16 remoteName[MAX_LOCATION]; DWORD size = MAX_LOCATION; volumePathName[wcslen(volumePathName)-1] = 0; if(WNetGetConnection(volumePathName, remoteName, &size) == ERROR_CONNECTION_UNAVAIL) { nr.lpRemoteName = remoteName; nr.lpLocalName = volumePathName; } else return false; } else return false; } EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowsProc, (LPARAM)&windowHandle); if(!windowHandle) { EnumWindows(EnumThreadWindowsProc, (LPARAM)&windowHandle); } if(WNetAddConnection3(windowHandle, &nr, null, null, CONNECT_INTERACTIVE|CONNECT_PROMPT) == NO_ERROR) result = true; return result; }
// ---------------------------------------------------------------------- // File Shot Engine // ---------------------------------------------------------------------- VOID FileShot(LPSNAPSHOT lpShot) { UINT cchExtDir; // Determine the Windows directory for file system scanning lpszExtDir = MYALLOC0(MAX_PATH * sizeof(TCHAR)); lpszWindowsDirName = MYALLOC0(MAX_PATH * sizeof(TCHAR)); GetSystemWindowsDirectory(lpszWindowsDirName, MAX_PATH); // length incl. NULL character GetVolumePathName(lpszWindowsDirName, lpszExtDir, MAX_PATH); lpszExtDir[MAX_PATH] = (TCHAR)'\0'; // Set the length of the Windows directory cchExtDir = _tcslen(lpszExtDir); //printf("%ws\n", lpszExtDir); if (0 < cchExtDir) { LPHEADFILE *lplpHFPrev; LPTSTR lpszSubExtDir; size_t i; lplpHFPrev = &lpShot->lpHF; lpszSubExtDir = lpszExtDir; for (i = 0; i <= cchExtDir; i++) { // Split each directory in string if (((TCHAR)';' == lpszExtDir[i]) || ((TCHAR)'\0' == lpszExtDir[i])) { LPHEADFILE lpHF; size_t j; lpszExtDir[i] = (TCHAR)'\0'; j = i; // remove all trailing spaces and backslashes while (0 < j) { --j; if (((TCHAR)'\\' == lpszExtDir[j]) || ((TCHAR)' ' == lpszExtDir[j])) { lpszExtDir[j] = (TCHAR)'\0'; } else { break; } } // if anything is left then process this directory if ((0 < j) && ((TCHAR)'\0' != lpszExtDir[j])) { lpHF = MYALLOC0(sizeof(HEADFILE)); *lplpHFPrev = lpHF; lplpHFPrev = &lpHF->lpBrotherHF; GetFilesSnap(lpShot, lpszSubExtDir, NULL, &lpHF->lpFirstFC); } lpszSubExtDir = &lpszExtDir[i + 1]; } } } // Update total count of all items lpShot->stCounts.cAll = lpShot->stCounts.cDirs + lpShot->stCounts.cFiles; // Print final file system shot count if ((dwBlacklist == 2 && performDynamicBlacklisting) || (performStaticBlacklisting)) { printf(" > Dirs: %d Files: %d Blacklisted Dirs: %d Blacklisted Files: %d\n", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles, lpShot->stCounts.cDirsBlacklist, lpShot->stCounts.cFilesBlacklist); } else { printf(" > Dirs: %d Files: %d\n", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles); } }
string GetVolumePath(const string& path) { std::vector<wchar_t> buf(MAX_PATH, L'\0'); if (GetVolumePathName(str::u16string(path).c_str(), buf.data(), MAX_PATH)) return str::u16string(buf.data()); return path; }
int __cdecl _tmain(int argc, TCHAR** argv) { TCHAR* lpPath; TCHAR mountPoint[MAX_PATH]; TCHAR volumeName[100]; LPTSTR lpVolumeDevicePath; HANDLE hVolume; if (argc > 1) { if (0 == lstrcmpi(_T("/trace"), argv[1]) || 0 == lstrcmpi(_T("-trace"), argv[1])) { NdasVolSetTrace(0x0000ffff, 0xffffffff, 5); --argc; ++argv; } } lpPath = (argc < 2) ? _T("C:") : argv[1]; lpVolumeDevicePath = lpPath; _tprintf(_T("Device Name: %s\n"), lpVolumeDevicePath); if (NdasIsNdasPath(lpVolumeDevicePath)) { _tprintf(_T("%s is on the NDAS device.\n"), lpVolumeDevicePath ); if (GetVolumePathName(lpVolumeDevicePath, mountPoint, RTL_NUMBER_OF(mountPoint))) { if (GetVolumeNameForVolumeMountPoint( mountPoint, volumeName, RTL_NUMBER_OF(volumeName))) { int len = lstrlen(volumeName); // _tprintf(_T("VolumeName=%s\n"), volumeName); // remove trailing backslash if (len > 0 && _T('\\') == volumeName[len-1]) { volumeName[len-1] = _T('\0'); } // replace \\?\Volume... to \\.\Volume... if (_T('\\') == volumeName[0] && _T('\\') == volumeName[1] && _T('?') == volumeName[2] && _T('\\') == volumeName[3]) { volumeName[2] = _T('.'); } // _tprintf(_T("VolumeName=%s\n"), volumeName); hVolume = CreateFile(volumeName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE != hVolume) { NDAS_SCSI_LOCATION loc; if (NdasGetNdasScsiLocationForVolume(hVolume,&loc)) { _tprintf(_T("NDAS_SCSI_LOCATION=(%d,%d,%d)"), loc.SlotNo, loc.TargetID, loc.LUN); } else { _tprintf(_T("NdasGetNdasScsiLocationForVolume failed.\n")); _tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError()); } CloseHandle(hVolume); } else { _tprintf(_T("Opening the volume %s failed.\n"), volumeName); _tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError()); } } else { _tprintf(_T("GetVolumeNameForVolumeMountPoint %s failed.\n"), mountPoint); _tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError()); } } else { _tprintf(_T("GetVolumePathName %s failed.\n"), lpVolumeDevicePath); _tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError()); } } else { _tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError()); } return 0; }
MMap::MMap (const Entry& entry, bool readwrite, bool preload, int64_t mapped_size) : Entry (entry), addr (NULL), first (NULL), msize (mapped_size), readwrite (readwrite) { DEBUG ("memory-mapping file \"" + Entry::name + "\"..."); struct stat sbuf; if (stat (Entry::name.c_str(), &sbuf)) throw Exception ("cannot stat file \"" + Entry::name + "\": " + strerror (errno)); mtime = sbuf.st_mtime; if (msize < 0) msize = sbuf.st_size - start; else if (start + msize > sbuf.st_size) throw Exception ("file \"" + Entry::name + "\" is smaller than expected"); bool delayed_writeback = false; if (readwrite) { #ifdef MRTRIX_WINDOWS const unsigned int length = 255; char root_path[length]; if (GetVolumePathName (Entry::name.c_str(), root_path, length)) { // Returns non-zero on success const unsigned int code = GetDriveType (root_path); switch (code) { case 0: // DRIVE_UNKNOWN DEBUG ("cannot get filesystem information on file \"" + Entry::name + "\": " + strerror (errno)); DEBUG (" defaulting to delayed write-back"); delayed_writeback = true; break; case 1: // DRIVE_NO_ROOT_DIR: DEBUG ("erroneous root path derived for file \"" + Entry::name + "\": " + strerror (errno)); DEBUG (" defaulting to delayed write-back"); delayed_writeback = true; break; case 2: // DRIVE_REMOVABLE DEBUG ("Drive for file \"" + Entry::name + "\" detected as removable; using memory-mapping"); break; case 3: // DRIVE_FIXED DEBUG ("Drive for file \"" + Entry::name + "\" detected as fixed; using memory-mapping"); break; case 4: // DRIVE_REMOTE DEBUG ("Drive for file \"" + Entry::name + "\" detected as network - using delayed write-back"); delayed_writeback = true; break; case 5: // DRIVE_CDROM DEBUG ("Drive for file \"" + Entry::name + "\" detected as CD-ROM - using delayed write-back"); delayed_writeback = true; break; case 6: // DRIVE_RAMDISK DEBUG ("Drive for file \"" + Entry::name + "\" detected as RAM - using memory-mapping"); break; } } else { DEBUG ("unable to query root drive path for file \"" + Entry::name + "\"; using delayed write-back"); delayed_writeback = true; } #else struct statfs fsbuf; if (statfs (Entry::name.c_str(), &fsbuf)) { DEBUG ("cannot get filesystem information on file \"" + Entry::name + "\": " + strerror (errno)); DEBUG (" defaulting to delayed write-back"); delayed_writeback = true; } if (fsbuf.f_type == 0xff534d42 /* CIFS */|| fsbuf.f_type == 0x6969 /* NFS */ || fsbuf.f_type == 0x65735546 /* FUSE */ || fsbuf.f_type == 0x517b /* SMB */ #ifdef MRTRIX_MACOSX || fsbuf.f_type == 0x0017 /* OSXFUSE */ #endif ) { DEBUG ("\"" + Entry::name + "\" appears to reside on a networked filesystem - using delayed write-back"); delayed_writeback = true; } #endif if (delayed_writeback) { try { first = new uint8_t [msize]; if (!first) throw 1; } catch (...) { throw Exception ("error allocating memory to hold mmap buffer contents"); } if (preload) { CONSOLE ("preloading contents of mapped file \"" + Entry::name + "\"..."); std::ifstream in (Entry::name.c_str(), std::ios::in | std::ios::binary); if (!in) throw Exception ("failed to open file \"" + Entry::name + "\": " + strerror (errno)); in.seekg (start, in.beg); in.read ((char*) first, msize); if (!in.good()) throw Exception ("error preloading contents of file \"" + Entry::name + "\": " + strerror(errno)); } else memset (first, 0, msize); DEBUG ("file \"" + Entry::name + "\" held in RAM at " + str ( (void*) first) + ", size " + str (msize)); return; } } // use regular memory-mapping: if ( (fd = open (Entry::name.c_str(), ( readwrite ? O_RDWR : O_RDONLY ), 0666)) < 0) throw Exception ("error opening file \"" + Entry::name + "\": " + strerror (errno)); try { #ifdef MRTRIX_WINDOWS HANDLE handle = CreateFileMapping ( (HANDLE) _get_osfhandle (fd), NULL, ( readwrite ? PAGE_READWRITE : PAGE_READONLY ), 0, start + msize, NULL); if (!handle) throw 0; addr = static_cast<uint8_t*> (MapViewOfFile (handle, ( readwrite ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ ), 0, 0, start + msize)); if (!addr) throw 0; CloseHandle (handle); #else addr = static_cast<uint8_t*> (mmap ( (char*) 0, start + msize, ( readwrite ? PROT_WRITE | PROT_READ : PROT_READ ), MAP_SHARED, fd, 0)); if (addr == MAP_FAILED) throw 0; #endif } catch (...) { close (fd); addr = NULL; throw Exception ("memory-mapping failed for file \"" + Entry::name + "\": " + strerror (errno)); } first = addr + start; DEBUG ("file \"" + Entry::name + "\" mapped at " + str ( (void*) addr) + ", size " + str (msize) + " (read-" + (readwrite ? "write" : "only") + ")"); }
int main (int argc, char *argv[]) { char buf[MAX_PATH*sizeof(WCHAR) + sizeof(REPARSE_DATA_BUFFER)]={'\0'}; char* dest_path=NULL; char* src_path=NULL; char* src_link=NULL; char* src_vol=NULL; char* dest_vol=NULL; HANDLE dir=NULL; REPARSE_DATA_BUFFER* reparse = (REPARSE_DATA_BUFFER*) buf; int path_len=0, data_len=0; DWORD ioctl_return = 0xdeadbeef; // To allow this to be used as a drop-in replacement for the posix ln command, // allow (and ignore) extra flags. if (argc != 3 && (argc !=4 || *argv[1] != '-')) { fputs("Usage: create-ntfs-junction <destination dir> <source dir>\n", stderr); return -1; } src_path = argv[argc-2]; path_len = strlen(src_path); if (src_path[path_len-1] == '\\') src_path[path_len-1] = '\0'; dest_path = argv[argc-1]; path_len = strlen(dest_path); if (dest_path[path_len-1] == '\\') dest_path[path_len-1] = '\0'; if (GetFileAttributes(src_path) == INVALID_FILE_ATTRIBUTES) { fprintf(stderr, "%s: No such animal.\n", src_path); return -1; } if (!GetVolumePathName(src_path, buf, MAX_PATH)) { fprintf(stderr, "Couldn't get volume name for '%s'.\n", src_path); return -1; } src_vol = _strdup(buf); if (!GetVolumePathName(dest_path, buf, MAX_PATH)) { fprintf(stderr, "Couldn't get volume name for '%s'.\n", dest_path); return -1; } dest_vol = _strdup(buf); if (strcmp(src_vol, dest_vol)) { fprintf(stderr, "Cannot create junction point across volume boundary.\n"); fprintf(stderr, " (from volume '%s' to volume '%s')\n", src_vol, dest_vol); return -1; } // End of input sanity checks; file system modifications may now occur. if (GetFileAttributes(dest_path) == INVALID_FILE_ATTRIBUTES) { if (!CreateDirectory(dest_path, NULL)) { switch(GetLastError()) { case ERROR_ALREADY_EXISTS: fprintf(stderr, "Can't create directory %s because it already exists " "(this should never happen).\n", dest_path); return -1; break; case ERROR_PATH_NOT_FOUND: fprintf(stderr, "Can't create directory %s because some part of the " "intermediate path doesn't exist.", dest_path); return -1; break; default: fprintf(stderr, "Unknown error occurred while trying to create " "directory %s.", dest_path); return -1; break; } } } dir = CreateFile(dest_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); strcpy_s(buf, 5, "\\??\\"); GetFullPathName(src_path, MAX_PATH, buf+4, NULL); src_link = _strdup(buf); memset(buf, 0, sizeof(buf)); path_len = MultiByteToWideChar(CP_ACP, 0, src_link, -1, reparse->MountPointReparseBuffer.PathBuffer, MAX_PATH*sizeof(WCHAR)); reparse->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; reparse->ReparseDataLength = (path_len+2)*sizeof(WCHAR) + 6; reparse->MountPointReparseBuffer.SubstituteNameLength = (path_len-1) * sizeof(WCHAR); reparse->MountPointReparseBuffer.PrintNameOffset = path_len * sizeof(WCHAR); data_len = reparse->ReparseDataLength + 8; if (!DeviceIoControl(dir, FSCTL_SET_REPARSE_POINT, &buf, data_len, NULL, 0, &ioctl_return, NULL)) { fprintf(stderr, "Junction point creation failed (ioctl_return=0x%x) (%d)\n", ioctl_return, GetLastError()); return 1; } return 0; }