Add W32 mountpoint resolving based on the disc number figured by ipodpatcher / sansap...
[Rockbox.git] / rbutil / rbutilqt / utils.cpp
blob3e3a5912b29a9effc9b29cc8ec15ac603d66e55e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "utils.h"
21 #ifdef UNICODE
22 #define _UNICODE
23 #endif
25 #include <QtCore>
26 #include <QDebug>
27 #include <cstdlib>
28 #include <stdio.h>
30 #if defined(Q_OS_WIN32)
31 #include <windows.h>
32 #include <tchar.h>
33 #include <winioctl.h>
34 #endif
36 // recursive function to delete a dir with files
37 bool recRmdir( const QString &dirName )
39 QString dirN = dirName;
40 QDir dir(dirN);
41 // make list of entries in directory
42 QStringList list = dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
43 QFileInfo fileInfo;
44 QString curItem, lstAt;
45 for(int i = 0; i < list.size(); i++){ // loop through all items of list
46 QString name = list.at(i);
47 curItem = dirN + "/" + name;
48 fileInfo.setFile(curItem);
49 if(fileInfo.isDir()) // is directory
50 recRmdir(curItem); // call recRmdir() recursively for deleting subdirectory
51 else // is file
52 QFile::remove(curItem); // ok, delete file
54 dir.cdUp();
55 return dir.rmdir(dirN); // delete empty dir and return if (now empty) dir-removing was successfull
59 //! @brief resolves the given path, ignoring case.
60 //! @param path absolute path to resolve.
61 //! @return returns exact casing of path, empty string if path not found.
62 QString resolvePathCase(QString path)
64 QStringList elems;
65 QString realpath;
67 elems = path.split("/", QString::SkipEmptyParts);
68 int start;
69 #if defined(Q_OS_WIN32)
70 // on windows we must make sure to start with the first entry (i.e. the
71 // drive letter) instead of a single / to make resolving work.
72 start = 1;
73 realpath = elems.at(0) + "/";
74 #else
75 start = 0;
76 realpath = "/";
77 #endif
79 for(int i = start; i < elems.size(); i++) {
80 QStringList direlems
81 = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System);
82 if(direlems.contains(elems.at(i), Qt::CaseInsensitive)) {
83 // need to filter using QRegExp as QStringList::filter(QString)
84 // matches any substring
85 QString expr = QString("^" + elems.at(i) + "$");
86 QRegExp rx = QRegExp(expr, Qt::CaseInsensitive);
87 QStringList a = direlems.filter(rx);
89 if(a.size() != 1)
90 return QString("");
91 if(!realpath.endsWith("/"))
92 realpath += "/";
93 realpath += a.at(0);
95 else
96 return QString("");
98 qDebug() << __func__ << path << "->" << realpath;
99 return realpath;
102 #if defined(Q_OS_WIN32)
103 QString getMountpointByDevice(int drive)
105 QString result;
106 for(int letter = 'A'; letter <= 'Z'; letter++) {
107 DWORD written;
108 HANDLE h;
109 TCHAR uncpath[MAX_PATH];
110 UCHAR buffer[0x400];
111 PVOLUME_DISK_EXTENTS extents = (PVOLUME_DISK_EXTENTS)buffer;
113 _stprintf(uncpath, _TEXT("\\\\.\\%c:"), letter);
114 h = CreateFile(uncpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
115 NULL, OPEN_EXISTING, 0, NULL);
116 if(h == INVALID_HANDLE_VALUE) {
117 qDebug() << "error getting extents for" << uncpath;
118 continue;
120 // get the extents
121 if(DeviceIoControl(h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
122 NULL, 0, extents, sizeof(buffer), &written, NULL)) {
123 for(int a = 0; a < extents->NumberOfDiskExtents; a++) {
124 qDebug() << "Disk:" << extents->Extents[a].DiskNumber;
125 if(extents->Extents[a].DiskNumber == drive) {
126 result = letter;
127 qDebug("found: %c", letter);
128 break;
135 return result;
138 #endif