bool my_issamepath(const TCHAR *path1, const TCHAR *path2) { TCHAR path1o[MAX_DPATH], path2o[MAX_DPATH]; my_canonicalize_path(path1, path1o, sizeof path1o / sizeof(TCHAR)); my_canonicalize_path(path2, path2o, sizeof path2o / sizeof(TCHAR)); if (!_tcsicmp(path1o, path2o)) return true; return false; }
int my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path) { TCHAR p1[MAX_DPATH]; TCHAR p2[MAX_DPATH]; int len, cnt; my_canonicalize_path(path1, p1, sizeof p1 / sizeof (TCHAR)); my_canonicalize_path(path2, p2, sizeof p2 / sizeof (TCHAR)); len = _tcslen (p1); if (len > _tcslen (p2)) len = _tcslen (p2); if (_tcsnicmp (p1, p2, len)) return 0; _tcscpy (path, p2 + len); cnt = 0; for (int i = 0; i < _tcslen (path); i++) { if (path[i] == '\\' || path[i] == '/') { path[i] = '/'; cnt++; } } write_log (_T("'%s' (%s) matched with '%s' (%s), extra = '%s'\n"), path1, p1, path2, p2, path); return cnt; }
bool my_resolvesoftlink(TCHAR *linkfile, int size) { TCHAR tmp[MAX_DPATH]; int v = my_resolvessymboliclink2(linkfile, size); if (v > 0) return true; if (v == 0) return false; if (my_resolveshortcut(linkfile,size)) return true; if (size > 0) { _tcscpy (tmp, linkfile); my_canonicalize_path (tmp, linkfile, size); } return false; }
static int my_resolvessymboliclink2(TCHAR *linkfile, int size) { WIN32_FIND_DATA fd; HANDLE h; int ret = -1; DWORD returnedDataSize; uae_u8 tmp[MAX_DPATH * 2]; TCHAR tmp2[MAX_DPATH]; h = FindFirstFile (linkfile, &fd); if (h == INVALID_HANDLE_VALUE) return -1; FindClose(h); if (fd.dwReserved0 != IO_REPARSE_TAG_SYMLINK || !(fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) return -1; h = CreateFile (linkfile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_REPARSE_POINT | FILE_FLAG_OPEN_REPARSE_POINT , NULL); if (h == INVALID_HANDLE_VALUE) return 0; if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, tmp, sizeof tmp, &returnedDataSize, NULL)) { REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)tmp; if (size > 0) { if (rdb->SymbolicLinkReparseBuffer.Flags & 1) { // SYMLINK_FLAG_RELATIVE _tcscpy (tmp2, linkfile); PathRemoveFileSpec (tmp2); _tcscat (tmp2, _T("\\")); TCHAR *p = tmp2 + _tcslen (tmp2); memcpy (p, (uae_u8*)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset, rdb->SymbolicLinkReparseBuffer.SubstituteNameLength); p[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0; } else { memcpy (tmp2, (uae_u8*)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset, rdb->SymbolicLinkReparseBuffer.SubstituteNameLength); tmp2[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0; } if (!_tcsnicmp (tmp2, _T("\\??\\"), 4)) { memmove (tmp2, tmp2 + 4, (_tcslen (tmp2 + 4) + 1) * sizeof (TCHAR)); } my_canonicalize_path (tmp2, linkfile, size); } ret = 1; } CloseHandle(h); return ret; }
// http://msdn.microsoft.com/en-us/library/aa969393.aspx bool my_resolveshortcut(TCHAR *linkfile, int size) { bool ok = false; HRESULT hres; IShellLink* psl; WCHAR szGotPath[MAX_PATH]; WCHAR szDescription[MAX_PATH]; WIN32_FIND_DATA wfd; const TCHAR *ext = _tcsrchr (linkfile, '.'); if (!ext || _tcsicmp (ext, _T(".lnk")) != 0) return false; // Get a pointer to the IShellLink interface. It is assumed that CoInitialize // has already been called. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Get a pointer to the IPersistFile interface. hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if (SUCCEEDED(hres)) { // Add code here to check return value from MultiByteWideChar // for success. // Load the shortcut. hres = ppf->Load(linkfile, STGM_READ); if (SUCCEEDED(hres)) { // Resolve the link. hres = psl->Resolve(NULL, SLR_NO_UI); if (SUCCEEDED(hres)) { // Get the path to the link target. hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH); if (SUCCEEDED(hres)) { // Get the description of the target. hres = psl->GetDescription(szDescription, MAX_PATH); if (SUCCEEDED(hres)) { if (size > 0) my_canonicalize_path (szGotPath, linkfile, size); ok = SUCCEEDED(hres); } } } } // Release the pointer to the IPersistFile interface. ppf->Release(); } // Release the pointer to the IShellLink interface. psl->Release(); } return ok; }