Skip to content

Commit fcedfe1

Browse files
committed
Implemented support for 'class' attribute, Validator::GetClass() and SetClass() & tests. For issue #58.
1 parent 9aa0e0d commit fcedfe1

File tree

6 files changed

+520
-1
lines changed

6 files changed

+520
-1
lines changed

include/shellanything/Validator.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ namespace shellanything
9494
/// </summary>
9595
void SetFileExists(const std::string & iFileExists);
9696

97+
/// <summary>
98+
/// Getter for the 'class' parameter.
99+
/// </summary>
100+
const std::string & GetClass() const;
101+
102+
/// <summary>
103+
/// Setter for the 'class' parameter.
104+
/// </summary>
105+
void SetClass(const std::string & iClass);
106+
97107
/// <summary>
98108
/// Getter for the 'inserve' parameter.
99109
/// </summary>
@@ -147,13 +157,16 @@ namespace shellanything
147157
bool ValidateProperties(const Context & context, const std::string & properties, bool inversed) const;
148158
bool ValidateFileExtensions(const Context & context, const std::string & file_extensions, bool inversed) const;
149159
bool ValidateExists(const Context & context, const std::string & file_exists, bool inversed) const;
160+
bool ValidateClass(const Context & context, const std::string & class_, bool inversed) const;
161+
bool ValidateClassSingle(const Context & context, const std::string & class_, bool inversed) const;
150162

151163
private:
152164
int mMaxFiles;
153165
int mMaxDirectories;
154166
std::string mProperties;
155167
std::string mFileExtensions;
156168
std::string mFileExists;
169+
std::string mClass;
157170
std::string mInverse;
158171
};
159172

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ add_library(shellanything STATIC
7171
Unicode.h
7272
Unicode.cpp
7373
Validator.cpp
74+
DriveClass.h
75+
DriveClass.cpp
7476
ErrorManager.h
7577
ErrorManager.cpp
7678
PropertyManager.h

src/DriveClass.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/**********************************************************************************
2+
* MIT License
3+
*
4+
* Copyright (c) 2018 Antoine Beauchamp
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*********************************************************************************/
24+
25+
#include "DriveClass.h"
26+
#include "shellanything/Validator.h"
27+
28+
#include <Windows.h>
29+
30+
namespace shellanything
31+
{
32+
33+
bool IsNetworkPath(const std::string & path)
34+
{
35+
if (path.size() >= 2 && path.substr(0, 2) == "\\\\")
36+
{
37+
// The path starts with \\
38+
// Extract hostname
39+
const char * hostname = &path[2];
40+
if (hostname[0] != '\0')
41+
{
42+
// Get first character of hostname
43+
char first = hostname[0];
44+
if ((first >= 'a' && first <= 'z') ||
45+
(first >= 'A' && first <= 'Z') ||
46+
(first >= '0' && first <= '9') )
47+
{
48+
return true;
49+
}
50+
}
51+
}
52+
return false;
53+
}
54+
55+
DRIVE_CLASS GetDriveClassFromPath(const std::string & path)
56+
{
57+
// Patch for DRIVE_CLASS_NETWORK.
58+
// The function GetDriveTypeA() will return DRIVE_UNKNOWN when the given path is a network path.
59+
// For example \\localhost\shared\public will be reported as DRIVE_UNKNOWN.
60+
// To get the expected DRIVE_REMOTE returned value, the shared directory 'shared' must be mapped to a drive letter.
61+
// For example, mapping \\localhost\shared to Z:, calling GetDriveTypeA("Z:\public") will return DRIVE_REMOTE.
62+
// This is not what we want. The value DRIVE_CLASS_NETWORK is expected when the given path is a network path.
63+
if (IsNetworkPath(path))
64+
return DRIVE_CLASS_NETWORK;
65+
66+
UINT dwDriveType = GetDriveTypeA(path.c_str());
67+
switch(dwDriveType)
68+
{
69+
case DRIVE_NO_ROOT_DIR:
70+
{
71+
// The function GetDriveTypeA() returns DRIVE_NO_ROOT_DIR on a path that does not exist,
72+
// if the given path is a file, or if the given path is a directory that is not the root directory.
73+
// The functions returns DRIVE_NO_ROOT_DIR even if the drive letter, of the given non-existing path, is a CD-ROM or DVD-Drive.
74+
// However, the function will return DRIVE_CDROM is the root path of the same path is used, even if there are no disk in the optical drive.
75+
// To work around these issues, try to resolve with the root path of the drive.
76+
std::string root_path = Validator::GetDrivePath(path);
77+
if (root_path.empty() || // We may be dealing with a network path
78+
root_path == path ) // We are already using a root drive path
79+
{
80+
// There is nothing we can do.
81+
return DRIVE_CLASS_UNKNOWN;
82+
}
83+
84+
// Try to resolve with the root path instead
85+
DRIVE_CLASS resolved = GetDriveClassFromPath(root_path);
86+
return resolved;
87+
}
88+
break;
89+
case DRIVE_REMOVABLE:
90+
return DRIVE_CLASS_REMOVABLE;
91+
case DRIVE_FIXED:
92+
return DRIVE_CLASS_FIXED;
93+
case DRIVE_REMOTE:
94+
return DRIVE_CLASS_NETWORK;
95+
case DRIVE_CDROM:
96+
return DRIVE_CLASS_OPTICAL;
97+
case DRIVE_RAMDISK:
98+
return DRIVE_CLASS_RAMDISK;
99+
100+
default:
101+
return DRIVE_CLASS_UNKNOWN;
102+
};
103+
}
104+
105+
DRIVE_CLASS GetDriveClassFromString(const std::string & value)
106+
{
107+
if (value == "drive:removable")
108+
return DRIVE_CLASS_REMOVABLE;
109+
if (value == "drive:fixed")
110+
return DRIVE_CLASS_FIXED;
111+
if (value == "drive:network")
112+
return DRIVE_CLASS_NETWORK;
113+
if (value == "drive:optical")
114+
return DRIVE_CLASS_OPTICAL;
115+
if (value == "drive:ramdisk")
116+
return DRIVE_CLASS_RAMDISK;
117+
if (value == "drive:unknown")
118+
return DRIVE_CLASS_UNKNOWN;
119+
120+
return DRIVE_CLASS_UNKNOWN;
121+
}
122+
123+
const char * ToString(DRIVE_CLASS & value)
124+
{
125+
switch(value)
126+
{
127+
case DRIVE_CLASS_REMOVABLE:
128+
return "drive:removable";
129+
case DRIVE_CLASS_FIXED:
130+
return "drive:fixed";
131+
case DRIVE_CLASS_NETWORK:
132+
return "drive:network";
133+
case DRIVE_CLASS_OPTICAL:
134+
return "drive:optical";
135+
case DRIVE_CLASS_RAMDISK:
136+
return "drive:ramdisk";
137+
default:
138+
return "drive:unknown";
139+
};
140+
}
141+
142+
143+
144+
} //namespace shellanything

src/DriveClass.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**********************************************************************************
2+
* MIT License
3+
*
4+
* Copyright (c) 2018 Antoine Beauchamp
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*********************************************************************************/
24+
25+
#ifndef SA_DRIVETYPES_H
26+
#define SA_DRIVETYPES_H
27+
28+
#include <string>
29+
30+
namespace shellanything
31+
{
32+
33+
enum DRIVE_CLASS
34+
{
35+
DRIVE_CLASS_UNKNOWN,
36+
DRIVE_CLASS_REMOVABLE,
37+
DRIVE_CLASS_FIXED,
38+
DRIVE_CLASS_NETWORK,
39+
DRIVE_CLASS_OPTICAL,
40+
DRIVE_CLASS_RAMDISK
41+
};
42+
43+
/// <summary>
44+
/// Define if the given path is a network path.
45+
/// The given path do not need to exist to be identified as a network path.
46+
/// </summary>
47+
/// <param name="path">The path to a valid file or directory.</param>
48+
/// <returns>Returns true when the given path is a network path. Returns false otherwise.</returns>
49+
bool IsNetworkPath(const std::string & path);
50+
51+
/// <summary>
52+
/// Returns the drive class based on the given path.
53+
/// </summary>
54+
/// <param name="path">The path to a valid file or directory.</param>
55+
/// <returns>Returns the drive class based on the given path. Returns DRIVE_CLASS_UNKNOWN if drive class cannot be found.</returns>
56+
DRIVE_CLASS GetDriveClassFromPath(const std::string & path);
57+
58+
/// <summary>
59+
/// Returns the drive class based on the given string.
60+
/// The given string value must match one of the values returned by the ToString() function.
61+
/// </summary>
62+
/// <param name="value">The string representation of a DRIVE_CLASS.</param>
63+
/// <returns>Returns the given drive type based on the given string. Returns DRIVE_CLASS_UNKNOWN if the string value is unknown.</returns>
64+
DRIVE_CLASS GetDriveClassFromString(const std::string & value);
65+
66+
/// <summary>
67+
/// Convert a DRIVE_CLASS value to a string representation.
68+
/// </summary>
69+
/// <param name="class_">The drive class value to convert. Must be a valid enumeration of DRIVE_CLASS.</param>
70+
/// <returns>Returns the string representation of the given DRIVE_CLASS enumeration value. Returns "drive:unknown" if 'class_' is not a valid value of DRIVE_CLASS.</returns>
71+
const char * ToString(DRIVE_CLASS & value);
72+
73+
} //namespace shellanything
74+
75+
#endif //SA_DRIVETYPES_H

0 commit comments

Comments
 (0)