Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/ChameleonPrefPane/Sources/PartitionInfoElement.mm

1//
2// PartitionInfoElement.mm
3// ChameleonPrefPane
4//
5// Powerful Partition Info class utility
6//
7// Created by Rekursor on 11-11-12.
8//
9
10#import "PartitionInfoElement.h"
11#import "ShellProcess.h"
12
13static NSUInteger sHdRedirTable[MAX_HD];
14
15@implementation PartitionInfoElement
16
17@synthesize descDict, bsdName, vUUID, vKind, vName, mediaPath, mediaRemovable, devInternal, devProtocol;
18@synthesize vAliasName, hidden;
19
20/// Create a list of all bsd partitions
21+(NSArray*) createBSDPartitionList
22{
23NSMutableArray* arr = [[NSMutableArray alloc] init];
24
25char line[256];
26ShellProcess p;
27
28p.open("ls -1 /dev/disk*");
29while( p.get_line(line, sizeof(line)-1))
30{
31size_t l = strlen(line);
32if (l==0 || strstr(line, "ls:")!=NULL) continue;
33if (line[l-1]) line[l-1]='\0';
34const char * p = strstr(line, "disk");
35NSString* s = [[NSString stringWithUTF8String: p] retain];
36[arr addObject: s];
37
38}
39p.close();
40
41return arr;
42}
43
44/// redirection table for disk swapping
45+(NSUInteger*) hdRedirTable
46{
47return sHdRedirTable;
48}
49
50/// extract disk number from bsdname spec
51-(int) diskNumber
52{
53int newDiskNum = (diskNum>=0 && diskNum <MAX_HD) ? sHdRedirTable[diskNum] : diskNum;
54return newDiskNum;
55}
56
57/// extract partition number from bsdname spec
58-(int) partitionNumber
59{
60return partNum; // todo extract d num from bsdname
61}
62
63-(NSString*) hdString
64{
65return [NSString stringWithFormat:@"hd(%d,%d)", [self diskNumber], [self partitionNumber]];
66}
67
68-(void) setDiskNumber: (int) d
69{
70diskNum = d;
71}
72
73-(void) setPartitionNumber:(int) p
74{
75partNum = p;
76}
77/// return true if partition extraction successfully executed, false otherwise
78-(bool) isValid
79{
80
81return (
82err==0
83// && [self isBootable] don't hide non bootable disk for now to be in sync
84// with chameleon as much as possible
85&& ![[self devProtocol] isEqual:@"Virtual Interface"]
86);
87}
88
89/// Extract a particular information from the disk partition dictionary from a key, generate a string value output
90-(NSString*) createStringValueWithKey: (NSString*) key
91{
92if (err) return @"";
93CFTypeRef o = [descDict objectForKey: key];
94if (o==nil) return @"";
95return (NSString*) CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), o);
96}
97
98/// main extraction method create a dictionary containing all needed information from disk arbitration API
99- (int) extractInfoWithBSDName: (NSString*) name withinSession:(DASessionRef) session
100{
101err = 0;
102
103NSRange rDisk = [name rangeOfString:@"disk"];
104NSRange rS = [name rangeOfString:@"s" options:NSBackwardsSearch] ;
105
106if (name == nil
107|| [name length] < 7
108|| rDisk.location == NSNotFound
109|| rS.location <5)
110{
111err = EINVAL;
112return err;
113}
114
115// extract disk and partition number
116int pos = rDisk.location+rDisk.length;
117int pos2 = rS.location+rS.length;
118NSString* sDisk = [name substringWithRange:
119 NSMakeRange(pos, rS.location - pos) ];
120NSString* sPart = [name substringFromIndex: pos2 ];
121
122diskNum = [sDiskintValue];
123partNum = [sPartintValue];
124
125 bsdName = name;
126
127bool mustRelease = (session == nil) ? true : false;
128
129if (session == nil)
130{
131session = DASessionCreate(NULL);
132}
133
134 DADiskRef disk;
135
136if (session == NULL)err = EINVAL;
137
138if (err == 0) {
139disk = DADiskCreateFromBSDName(NULL, session, [bsdName UTF8String] );
140if (disk == NULL) err = EINVAL;
141}
142
143if (err == 0) {
144descDict = (NSDictionary*) DADiskCopyDescription(disk);
145[descDict retain];
146
147if (descDict == NULL) err = EINVAL;
148}
149
150if (err == 0) {
151self.vUUID = [self createStringValueWithKey: @"DAVolumeUUID"];
152self.vName = [self createStringValueWithKey: @"DAVolumeName"];
153self.vKind = [self createStringValueWithKey: @"DAVolumeKind"];
154self.mediaPath = [self createStringValueWithKey: @"DAMediaPath"];
155self.devProtocol = [self createStringValueWithKey: @"DADeviceProtocol"];
156
157devInternal = (bool) [[descDict objectForKey: @"DADeviceInternal"] boolValue];
158mediaRemovable = (bool) [[descDict objectForKey: @"DAMediaRemovable"] boolValue];
159
160self.vAliasName = self.vName; // by default renamed = original part name
161}
162
163// Clean up.
164
165if (disk != NULL)CFRelease(disk);
166if (session != NULL && mustRelease) CFRelease(session);
167
168return err;
169}
170
171+(NSMutableArray*)extractInfoWithBSDNames: (NSArray*) bsdNames
172{
173return [PartitionInfoElement extractInfoWithBSDNames:bsdNames withArray: nil];
174}
175
176/// main extraction method create a dictionary of PartitionInfoElement objects containing all needed information from disk arbitration API
177+ (NSMutableArray*) extractInfoWithBSDNames: (NSArray*) names withArray:(NSMutableArray*) arr
178{
179NSArray* partArr = [PartitionInfoElement createBSDPartitionList];
180if (arr == nil)
181arr = [[NSMutableArray alloc ] init];
182
183if (partArr!=nil && [partArr count]>0)
184{
185DASessionRef session = DASessionCreate(NULL);
186for (NSString* part in partArr)
187{
188PartitionInfoElement* elt =
189[[PartitionInfoElement alloc] initWithBSDName: part withinSession: session];
190if (elt!=nil && [[elt vName] length] >0 && [elt isValid] )
191[arr addObject:elt];
192}
193if (session!=nil) CFRelease(session);
194}
195
196return arr;
197}
198
199- (int) extractInfoWithBSDName: (NSString*) name
200{
201return [self extractInfoWithBSDName:name withinSession: nil];
202}
203
204-(bool) isBootable
205{
206bool bootable = false;
207NSFileManager* mgr = [NSFileManager defaultManager];
208NSString *fmt = @"/Volumes/%@%s";
209// that Windows is the name of WIN32 bootable disk dir ...
210if(
211[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/System/Library/Extensions" ]] ||
212 [mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/ntldr" ]] ||
213[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/bootmgr" ]] ||
214[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/boot/bcd" ]] ||
215[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/pagefile.sys" ]] ||
216[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/hiberfil.sys" ]]
217 )
218bootable=true;
219else if ([vName rangeOfString:@"ext"].location != NSNotFound) // linux ?
220bootable = true;
221return bootable;
222}
223
224/// Return the partition image index according to its file system
225-(int) imageIndexFromFs
226{
227
228if ( [[self vKind] rangeOfString:@"hfs"].location != NSNotFound )
229return 0; // Mac
230if ( [[self vKind] rangeOfString:@"fat"].location != NSNotFound ||
231 [[self vKind] rangeOfString:@"ntfs"].location != NSNotFound ||
232 [[self vKind] rangeOfString:@"dos"].location != NSNotFound )
233return 1; // Windows
234if ( [[self vKind] rangeOfString:@"ext"].location != NSNotFound )
235return 2; // Linux
236
237return 10; // unknown
238}
239
240/// Volume label trimming utility function
241+(NSString*) removesSpacesFromLabel:(NSString*) label
242{
243if (label == nil || [label length]==0) return label;
244return [label stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
245}
246
247/// make the object description available for NSLog() debug purpose
248-(NSString*) description
249{
250NSString* format =
251@"(\n"
252 " bsdName %@\n deviceProtocol %@\n deviceInternal %i\n"
253 " volumeName %@\n volumeKind %@\n volumeUUID %@\n"
254 " mediaPath %@\n mediaRemovable %i\n"
255 ")";
256NSString* value = [NSString stringWithFormat: format,
257 self.bsdName, self.devProtocol, self.devInternal,
258 self.vName, self.vKind, self.vUUID,
259 self.mediaPath, self.mediaRemovable ];
260return value;
261}
262
263
264/// initialize a partition element with DA partition info
265-(id) initWithBSDName:(NSString*) name
266{
267[super init];
268diskNum = partNum = -1;
269err = [self extractInfoWithBSDName: name withinSession: nil];
270return self;
271}
272
273/// initialize a partition element with DA partition info and an optional opened session
274-(id) initWithBSDName:(NSString*) name withinSession:(DASessionRef) session
275{
276[super init];
277diskNum = partNum = -1;
278err = [self extractInfoWithBSDName: name withinSession: session];
279
280return self;
281}
282
283/// release created objects
284-(void) dealloc
285{
286if (descDict != nil) [descDict release];
287if (bsdName != nil) [bsdName release];
288if (vUUID != nil) [vUUID release];
289if (vKind != nil) [vKind release];
290if (vName != nil) [vName release];
291if (mediaPath != nil) [mediaPath release];
292
293if (vAliasName != nil) [vAliasName release];
294
295[super dealloc];
296}
297
298@end
299

Archive Download this file

Revision: 366