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)", diskNum, partNum];
66}
67
68/// return true if partition extraction successfully executed, false otherwise
69-(bool) isValid
70{
71return err==0;
72}
73
74/// Extract a particular information from the disk partition dictionary from a key, generate a string value output
75-(NSString*) createStringValueWithKey: (NSString*) key
76{
77if (err) return @"";
78CFTypeRef o = [descDict objectForKey: key];
79if (o==nil) return @"";
80return (NSString*) CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), o);
81}
82
83/// main extraction method create a dictionary containing all needed information from disk arbitration API
84- (int) extractInfoWithBSDName: (NSString*) name withinSession:(DASessionRef) session
85{
86err = 0;
87
88NSRange rDisk = [name rangeOfString:@"disk"];
89NSRange rS = [name rangeOfString:@"s" options:NSBackwardsSearch] ;
90
91if (name == nil
92|| [name length] < 7
93|| rDisk.location == NSNotFound
94|| rS.location <5)
95{
96err = EINVAL;
97return err;
98}
99
100// extract disk and partition number
101int pos = rDisk.location+rDisk.length;
102int pos2 = rS.location+rS.length;
103NSString* sDisk = [name substringWithRange:
104 NSMakeRange(pos, rS.location - pos) ];
105NSString* sPart = [name substringFromIndex: pos2 ];
106
107diskNum = [sDiskintValue];
108partNum = [sPartintValue];
109
110 bsdName = name;
111
112bool mustRelease = (session == nil) ? true : false;
113
114if (session == nil)
115{
116session = DASessionCreate(NULL);
117}
118
119 DADiskRef disk;
120
121if (session == NULL)err = EINVAL;
122
123if (err == 0) {
124disk = DADiskCreateFromBSDName(NULL, session, [bsdName UTF8String] );
125if (disk == NULL) err = EINVAL;
126}
127
128if (err == 0) {
129descDict = (NSDictionary*) DADiskCopyDescription(disk);
130[descDict retain];
131
132if (descDict == NULL) err = EINVAL;
133}
134
135if (err == 0) {
136self.vUUID = [self createStringValueWithKey: @"DAVolumeUUID"];
137self.vName = [self createStringValueWithKey: @"DAVolumeName"];
138self.vKind = [self createStringValueWithKey: @"DAVolumeKind"];
139self.mediaPath = [self createStringValueWithKey: @"DAMediaPath"];
140self.devProtocol = [self createStringValueWithKey: @"DADeviceProtocol"];
141
142devInternal = (bool) [[descDict objectForKey: @"DADeviceInternal"] boolValue];
143mediaRemovable = (bool) [[descDict objectForKey: @"DAMediaRemovable"] boolValue];
144
145self.vAliasName = self.vName; // by default renamed = original part name
146}
147
148// Clean up.
149
150if (disk != NULL)CFRelease(disk);
151if (session != NULL && mustRelease) CFRelease(session);
152
153return err;
154}
155
156+(NSMutableArray*)extractInfoWithBSDNames: (NSArray*) bsdNames
157{
158return [PartitionInfoElement extractInfoWithBSDNames:bsdNames withArray: nil];
159}
160
161/// main extraction method create a dictionary of PartitionInfoElement objects containing all needed information from disk arbitration API
162+ (NSMutableArray*) extractInfoWithBSDNames: (NSArray*) names withArray:(NSMutableArray*) arr
163{
164NSArray* partArr = [PartitionInfoElement createBSDPartitionList];
165if (arr == nil)
166arr = [[NSMutableArray alloc ] init];
167
168if (partArr!=nil && [partArr count]>0)
169{
170DASessionRef session = DASessionCreate(NULL);
171for (NSString* part in partArr)
172{
173PartitionInfoElement* elt =
174[[PartitionInfoElement alloc] initWithBSDName: part withinSession: session];
175if (elt!=nil && [[elt vName] length] >0)
176[arr addObject:elt];
177}
178if (session!=nil) CFRelease(session);
179}
180
181return arr;
182}
183
184- (int) extractInfoWithBSDName: (NSString*) name
185{
186return [self extractInfoWithBSDName:name withinSession: nil];
187}
188
189-(bool) isBootable
190{
191bool bootable = false;
192NSFileManager* mgr = [NSFileManager defaultManager];
193NSString *fmt = @"/Volumes/%@%s";
194// that Windows is the name of WIN32 bootable disk dir ...
195if(
196[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/System/Library/Extensions" ]] ||
197 [mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/ntldr" ]] ||
198[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/bootmgr" ]] ||
199[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/boot/bcd" ]] ||
200[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/pagefile.sys" ]] ||
201[mgr fileExistsAtPath: [NSString stringWithFormat: fmt, vName, "/hiberfil.sys" ]]
202 )
203bootable=true;
204else if ([vName rangeOfString:@"ext"].location != NSNotFound) // linux ?
205bootable = true;
206return bootable;
207}
208
209/// Return the partition image index according to its file system
210-(int) imageIndexFromFs
211{
212
213if ( [[self vKind] rangeOfString:@"hfs"].location != NSNotFound )
214return 0; // Mac
215if ( [[self vKind] rangeOfString:@"fat"].location != NSNotFound ||
216 [[self vKind] rangeOfString:@"ntfs"].location != NSNotFound ||
217 [[self vKind] rangeOfString:@"dos"].location != NSNotFound )
218return 1; // Windows
219if ( [[self vKind] rangeOfString:@"ext"].location != NSNotFound )
220return 2; // Linux
221
222return 10; // unknown
223}
224
225/// Volume label trimming utility function
226+(NSString*) removesSpacesFromLabel:(NSString*) label
227{
228if (label == nil || [label length]==0) return label;
229return [label stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
230}
231
232/// make the object description available for NSLog() debug purpose
233-(NSString*) description
234{
235NSString* format =
236@"(\n"
237 " bsdName %@\n deviceProtocol %@\n deviceInternal %i\n"
238 " volumeName %@\n volumeKind %@\n volumeUUID %@\n"
239 " mediaPath %@\n mediaRemovable %i\n"
240 ")";
241NSString* value = [NSString stringWithFormat: format,
242 self.bsdName, self.devProtocol, self.devInternal,
243 self.vName, self.vKind, self.vUUID,
244 self.mediaPath, self.mediaRemovable ];
245return value;
246}
247
248
249/// initialize a partition element with DA partition info
250-(id) initWithBSDName:(NSString*) name
251{
252[super init];
253diskNum = partNum = -1;
254err = [self extractInfoWithBSDName: name withinSession: nil];
255return self;
256}
257
258/// initialize a partition element with DA partition info and an optional opened session
259-(id) initWithBSDName:(NSString*) name withinSession:(DASessionRef) session
260{
261[super init];
262diskNum = partNum = -1;
263err = [self extractInfoWithBSDName: name withinSession: session];
264
265return self;
266}
267
268/// release created objects
269-(void) dealloc
270{
271if (descDict != nil) [descDict release];
272if (bsdName != nil) [bsdName release];
273if (vUUID != nil) [vUUID release];
274if (vKind != nil) [vKind release];
275if (vName != nil) [vName release];
276if (mediaPath != nil) [mediaPath release];
277
278if (vAliasName != nil) [vAliasName release];
279
280[super dealloc];
281}
282
283@end
284

Archive Download this file

Revision: 346