Alex's memory leak fixes and timeout changes.
[ITFoundation.git] / ITAppleEventTools.m
1 /*
2  *  ITAppleEventTools.c
3  *  ITFoundation
4  *
5  *  Created by Alexander Strange on Wed Feb 11 2004.
6  *  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
7  *
8  */
9
10 #import "ITDebug.h"
11 #import "ITAppleEventTools.h"
12
13 NSAppleEventDescriptor *ITSendAEWithString(NSString *sendString, FourCharCode evClass, FourCharCode evID,const ProcessSerialNumber *psn)
14 {
15     //Add error checking...
16     pid_t pid;
17     
18     const char *usendString = [sendString UTF8String];
19     
20     AppleEvent sendEvent, replyEvent;
21     NSAppleEventDescriptor *send, *recv;
22     AEDesc resultDesc;
23     DescType resultType;
24     Size resultSize;
25     
26     AEBuildError buildError;
27     OSStatus berr,err;
28     
29     if ((GetProcessPID(psn, &pid) == noErr) && (pid == 0)) {
30         ITDebugLog(@"Error getting PID of application.");
31         return nil;
32     }
33     
34     berr = AEBuildAppleEvent(evClass, evID, typeProcessSerialNumber,psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, usendString);
35     send = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&sendEvent] autorelease];
36     if (!berr) [send logDesc];
37     
38     if (berr) {
39         ITDebugLog(@"Error: %d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[sendString substringToIndex:buildError.fErrorPos]);
40     }
41     
42     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, /*kAEDefaultTimeout*/60, NULL, NULL);
43     
44     err = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
45     if (resultSize == 0 || err != 0) {
46         return nil;
47     }
48     
49     AEGetParamDesc(&replyEvent, keyDirectObject, resultType, &resultDesc);
50     
51     recv = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&resultDesc] autorelease];
52     [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&replyEvent] autorelease];
53     if (!err) [recv logDesc];
54     
55     if (err) {
56         ITDebugLog(@"Send Error: %i",err);
57     }
58     return recv;
59 }
60
61 NSAppleEventDescriptor *ITSendAEWithStringAndObject(NSString *sendString, const AEDesc *object, FourCharCode evClass, FourCharCode evID,const ProcessSerialNumber *psn)
62 {
63     //Add error checking...
64     pid_t pid;
65     
66     const char *usendString = [sendString UTF8String];
67     
68     AppleEvent sendEvent, replyEvent;
69     NSAppleEventDescriptor *send, *recv;
70     AEDesc resultDesc;
71     DescType resultType;
72     Size resultSize;
73     
74     AEBuildError buildError;
75     OSStatus berr,err;
76     
77     if ((GetProcessPID(psn, &pid) == noErr) && (pid == 0)) {
78         ITDebugLog(@"Error getting PID of application.");
79         return nil;
80     }
81     
82     berr = AEBuildAppleEvent(evClass, evID, typeProcessSerialNumber,psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, usendString);
83     send = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&sendEvent] autorelease];
84     if (!berr) [send logDesc];
85     
86     if (berr) {
87         ITDebugLog(@"Error: %d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[sendString substringToIndex:buildError.fErrorPos]);
88     }
89     err = AEPutParamDesc(&sendEvent, keyDirectObject, object);
90     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, /*kAEDefaultTimeout*/60, NULL, NULL);
91     
92     err = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
93     if (resultSize == 0 || err != 0) {
94         return nil;
95     }
96     
97     AEGetParamDesc(&replyEvent, keyDirectObject, resultType, &resultDesc);
98     
99     recv = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&resultDesc] autorelease];
100     [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&replyEvent] autorelease];
101     if (!err) [recv logDesc];
102     
103     if (err) {
104         ITDebugLog(@"Send Error: %i",err);
105     }
106     return recv;
107 }
108
109 NSAppleEventDescriptor *ITSendAEWithKey(FourCharCode reqKey, FourCharCode evClass, FourCharCode evID,const ProcessSerialNumber *psn)
110 {
111     //Add error checking...
112     pid_t pid;
113         NSString *sendString = [NSString stringWithFormat:@"'----':obj { form:'prop', want:type('prop'), seld:type('%c%c%c%c'), from:'null'() }", (reqKey >> 24), (reqKey >> 16) & 0xff, (reqKey >> 8) & 0xff, reqKey & 0xff];
114     const char *usendString = [sendString UTF8String];
115     
116     AppleEvent sendEvent, replyEvent;
117     NSAppleEventDescriptor *send, *recv;
118     AEDesc resultDesc;
119     DescType resultType;
120     Size resultSize;
121     
122     AEBuildError buildError;
123     OSStatus berr,err;
124     
125     if ((GetProcessPID(psn, &pid) == noErr) && (pid == 0)) {
126         ITDebugLog(@"Error getting PID of application.");
127         return nil;
128     }
129     
130     berr = AEBuildAppleEvent(evClass, evID, typeProcessSerialNumber,psn, sizeof(ProcessSerialNumber), kAutoGenerateReturnID, 0, &sendEvent, &buildError, usendString);
131     send = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&sendEvent] autorelease];
132     if (!berr) [send logDesc];
133     
134     if (berr) {
135         ITDebugLog(@"Error: %d:%d at \"%@\"",(int)buildError.fError,buildError.fErrorPos,[sendString substringToIndex:buildError.fErrorPos]);
136     }
137     
138     err = AESend(&sendEvent, &replyEvent, kAEWaitReply, kAENormalPriority, /*kAEDefaultTimeout*/60, NULL, NULL);
139     
140     err = AESizeOfParam(&replyEvent, keyDirectObject, &resultType, &resultSize);
141     if (resultSize == 0 || err != 0) {
142         return nil;
143     }
144     
145     AEGetParamDesc(&replyEvent, keyDirectObject, resultType, &resultDesc);
146     
147     recv = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&resultDesc] autorelease];
148     [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&replyEvent] autorelease];
149     if (!err) [recv logDesc];
150     
151     if (err) {
152         ITDebugLog(@"Send Error: %i",err);
153     }
154     return recv;
155 }
156
157 NSAppleEventDescriptor *ITSendAE(FourCharCode eClass, FourCharCode eID,const ProcessSerialNumber *psn)
158 {
159     AEDesc dest;
160     int pid;
161     
162     AppleEvent event, reply;
163     OSStatus cerr,cerr2,err;
164     NSAppleEventDescriptor *nsd, *nse, *nsr;
165     if ((GetProcessPID(psn, &pid) == noErr) && (pid == 0)) {
166         ITDebugLog(@"Error getting PID of application.");
167         return nil;
168     }
169     cerr = AECreateDesc(typeProcessSerialNumber,psn,sizeof(ProcessSerialNumber),&dest);
170     nsd = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&dest] autorelease];
171     cerr2 = AECreateAppleEvent(eClass,eID,&dest,kAutoGenerateReturnID,kAnyTransactionID,&event);
172     nse = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&event] autorelease];
173     if (!cerr2) [nse logDesc];
174     err = AESend(&event, &reply, kAENoReply, kAENormalPriority, /*kAEDefaultTimeout*/60, NULL, NULL);
175     nsr = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply] autorelease];
176     [nsr logDesc];
177     return nsr;
178 }
179
180 @implementation NSAppleEventDescriptor (ITAELogging)
181 -(void) logDesc
182 {
183     Handle xx;
184     AEPrintDescToHandle([self aeDesc],&xx);
185     ITDebugLog(@"AE Descriptor: %s", *xx);
186     DisposeHandle(xx);
187 }
188 @end