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

Archive Download this file

Revision: 347