Beispiel #1
0
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



}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/*
	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;
}
Beispiel #7
0
        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
}
Beispiel #9
0
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;
}
Beispiel #10
0
/*
 * 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;
}
Beispiel #12
0
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 );
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
// ----------------------------------------------------------------------
// 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);
	}
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
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;
}