1/* 2 DNR.c - DNR library for MPW 3 4 (c) Copyright 1988 by Apple Computer. All rights reserved. 5 PowerPC corrections by Eric Scouten, December 2, 1994. 6 7*/ 8 9#define MPW3.0 10 11#include <Carbon.h> 12#if 0 13#include <OSUtils.h> 14#include <Errors.h> 15#include <Files.h> 16#include <Resources.h> 17#include <Memory.h> 18#include <Traps.h> 19#include <Gestalt.h> 20#include <Folders.h> 21#include <MixedMode.h> 22#endif 23 24#define OPENRESOLVER 1L 25#define CLOSERESOLVER 2L 26#define STRTOADDR 3L 27#define ADDRTOSTR 4L 28#define ENUMCACHE 5L 29#define ADDRTONAME 6L 30#define HINFO 7L 31#define MXINFO 8L 32 33Handle codeHndl = nil; 34UniversalProcPtr dnr = nil; 35 36enum { 37 NUM_ALT_ADDRS = 4 38}; 39 40struct hostInfo { 41 long rtnCode; 42 char cname[255]; 43 SInt8 filler; /* Filler for proper byte alignment */ 44 unsigned long addr[NUM_ALT_ADDRS]; 45}; 46typedef struct hostInfo hostInfo; 47 48static pascal OSErr (*mzSysEnvirons)(int versionRequested, SysEnvRec *theworld); 49static pascal OSErr (*mzGetWDInfo)(short wdRefNum, short *vRefNum, long *dirID, long *procID); 50static pascal UniversalProcPtr (*mzNewRoutineDescriptor) (ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA); 51static long (*mzCallUniversalProc)(UniversalProcPtr theProcPtr, ProcInfoType theProcInfo, ...); 52 53#define NewRoutineDescriptor mzNewRoutineDescriptor 54#define CallUniversalProc mzCallUniversalProc 55 56void GetSystemFolder(short *vRefNumP, long *dirIDP) 57{ 58 SysEnvRec info; 59 long wdProcID; 60 61 mzSysEnvirons(1, &info); 62 if (mzGetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) { 63 *vRefNumP = 0; 64 *dirIDP = 0; 65 } 66 } 67 68void GetCPanelFolder(short *vRefNumP, long *dirIDP) 69{ 70 Boolean hasFolderMgr = false; 71 long feature; 72 73 if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) 74 hasFolderMgr = true; 75 if (!hasFolderMgr) { 76 GetSystemFolder(vRefNumP, dirIDP); 77 return; 78 } 79 else { 80 if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, vRefNumP, dirIDP) != noErr) { 81 *vRefNumP = 0; 82 *dirIDP = 0; 83 } 84 } 85 } 86 87/* SearchFolderForDNRP is called to search a folder for files that might 88 contain the 'dnrp' resource */ 89short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID) 90{ 91 HParamBlockRec fi; 92 Str255 filename; 93 short refnum; 94 95 fi.fileParam.ioCompletion = nil; 96 fi.fileParam.ioNamePtr = filename; 97 fi.fileParam.ioVRefNum = vRefNum; 98 fi.fileParam.ioDirID = dirID; 99 fi.fileParam.ioFDirIndex = 1; 100 101 while (PBHGetFInfoSync(&fi) == noErr) { 102 /* scan system folder for driver resource files of specific type & creator */ 103 if (fi.fileParam.ioFlFndrInfo.fdType == targetType && 104 fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) { 105 /* found the MacTCP driver file? */ 106 refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm); 107 if (GetIndResource('dnrp', 1) == NULL) 108 CloseResFile(refnum); 109 else 110 return refnum; 111 } 112 /* check next file in system folder */ 113 fi.fileParam.ioFDirIndex++; 114 fi.fileParam.ioDirID = dirID; /* PBHGetFInfo() clobbers ioDirID */ 115 } 116 return(-1); 117 } 118 119 120 121/* OpenOurRF is called to open the MacTCP driver resources */ 122 123short OpenOurRF() 124{ 125 short refnum; 126 short vRefNum; 127 long dirID; 128 129 /* first search Control Panels for MacTCP 1.1 */ 130 GetCPanelFolder(&vRefNum, &dirID); 131 refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID); 132 if (refnum != -1) return(refnum); 133 134 /* next search System Folder for MacTCP 1.0.x */ 135 GetSystemFolder(&vRefNum, &dirID); 136 refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); 137 if (refnum != -1) return(refnum); 138 139 /* finally, search Control Panels for MacTCP 1.0.x */ 140 GetCPanelFolder(&vRefNum, &dirID); 141 refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); 142 if (refnum != -1) return(refnum); 143 144 return -1; 145 } 146 147 148 149 150typedef OSErr (*OpenResolverProcPtr)(long selector, char* fileName); 151 152enum { 153 uppOpenResolverProcInfo = kCStackBased 154 | RESULT_SIZE(SIZE_CODE(sizeof(long))) 155 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) 156 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *))) 157}; 158 159#if USESROUTINEDESCRIPTORS 160typedef UniversalProcPtr OpenResolverUPP; 161 162#define NewOpenResolverProc(userRoutine) \ 163 (OpenResolverUPP) mzNewRoutineDescriptor(userRoutine, uppOpenResolverProcInfo, GetCurrentISA()) 164#define CallOpenResolverProc(userRoutine, selector, filename) \ 165 CallUniversalProc(userRoutine, uppOpenResolverProcInfo, selector, filename) 166#else 167typedef OpenResolverProcPtr OpenResolverUPP; 168 169#define NewOpenResolverProc(userRoutine) \ 170 (OpenResolverUPP)(userRoutine) 171#define CallOpenResolverProc(userRoutine, selector, filename) \ 172 (*userRoutine)(selector, filename) 173#endif 174 175 176 177pascal OSErr OpenResolver(fileName) 178char *fileName; 179{ 180 short refnum; 181 OSErr rc; 182 183 if (dnr != nil) 184 /* resolver already loaded in */ 185 return(noErr); 186 187 /* open the MacTCP driver to get DNR resources. Search for it based on 188 creator & type rather than simply file name */ 189 refnum = OpenOurRF(); 190 191 /* ignore failures since the resource may have been installed in the 192 System file if running on a Mac 512Ke */ 193 194 /* load in the DNR resource package */ 195 codeHndl = GetIndResource('dnrp', 1); 196 if (codeHndl == nil) { 197 /* can't open DNR */ 198 return(ResError()); 199 } 200 201 DetachResource(codeHndl); 202 if (refnum != -1) { 203 CloseResFile(refnum); 204 } 205 206 /* lock the DNR resource since it cannot be reloated while opened */ 207 HLock(codeHndl); 208 dnr = (UniversalProcPtr) *codeHndl; 209 210 /* call open resolver */ 211 rc = CallOpenResolverProc((OpenResolverUPP) dnr, OPENRESOLVER, fileName); 212 if (rc != noErr) { 213 /* problem with open resolver, flush it */ 214 HUnlock(codeHndl); 215 DisposeHandle(codeHndl); 216 dnr = nil; 217 } 218 return(rc); 219} 220 221 222 223typedef OSErr (*CloseResolverProcPtr)(long selector); 224 225enum { 226 uppCloseResolverProcInfo = kCStackBased 227 | RESULT_SIZE(SIZE_CODE(sizeof(long))) 228 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) 229}; 230 231#if USESROUTINEDESCRIPTORS 232typedef UniversalProcPtr CloseResolverUPP; 233 234#define NewCloseResolverProc(userRoutine) \ 235 (CloseResolverUPP) mzNewRoutineDescriptor(userRoutine, uppCloseResolverProcInfo, GetCurrentISA()) 236#define CallCloseResolverProc(userRoutine, selector) \ 237 CallUniversalProc(userRoutine, uppCloseResolverProcInfo, selector) 238#else 239typedef CloseResolverProcPtr CloseResolverUPP; 240 241#define NewCloseResolverProc(userRoutine) \ 242 (CloseResolverUPP)(userRoutine) 243#define CallCloseResolverProc(userRoutine, selector) \ 244 (*userRoutine)(selector) 245#endif 246 247 248 249pascal OSErr CloseResolver() 250{ 251 if (dnr == nil) 252 /* resolver not loaded error */ 253 return(notOpenErr); 254 255 /* call close resolver */ 256 CallCloseResolverProc((CloseResolverUPP) dnr, CLOSERESOLVER); 257 258 /* release the DNR resource package */ 259 HUnlock(codeHndl); 260 DisposeHandle(codeHndl); 261 dnr = nil; 262 return(noErr); 263} 264 265 266 267 268typedef OSErr (*StrToAddrProcPtr)(long selector, char* hostName, struct hostInfo* rtnStruct, 269 long resultProc, char* userData); 270 271enum { 272 uppStrToAddrProcInfo = kCStackBased 273 | RESULT_SIZE(SIZE_CODE(sizeof(long))) 274 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) 275 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *))) 276 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(struct hostInfo *))) 277 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long))) 278 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(char *))) 279}; 280 281#if USESROUTINEDESCRIPTORS 282typedef UniversalProcPtr StrToAddrUPP; 283 284#define NewStrToAddrProc(userRoutine) \ 285 (StrToAddrUPP) mzNewRoutineDescriptor(userRoutine, uppStrToAddrProcInfo, GetCurrentISA()) 286#define CallStrToAddrProc(userRoutine, selector, hostName, rtnStruct, resultProc, userData) \ 287 CallUniversalProc(userRoutine, uppStrToAddrProcInfo, selector, hostName, rtnStruct, resultProc, userData) 288#else 289typedef StrToAddrProcPtr StrToAddrUPP; 290 291#define NewStrToAddrProc(userRoutine) \ 292 (StrToAddrUPP)(userRoutine) 293#define CallStrToAddrProc(userRoutine, selector, hostName, rtnStruct, resultProc, userData) \ 294 (*userRoutine)(selector, hostName, rtnStruct, resultProc, userData) 295#endif 296 297 298 299pascal OSErr StrToAddr(hostName, rtnStruct, resultproc, userDataPtr) 300char *hostName; 301struct hostInfo *rtnStruct; 302long resultproc; 303char *userDataPtr; 304{ 305 if (dnr == nil) 306 /* resolver not loaded error */ 307 return(notOpenErr); 308 309 return(CallStrToAddrProc((StrToAddrUPP) dnr, STRTOADDR, hostName, (void*) rtnStruct, 310 resultproc, userDataPtr)); 311} 312 313 314typedef OSErr (*AddrToStrProcPtr)(long selector, long address, char* hostName); 315 316enum { 317 uppAddrToStrProcInfo = kCStackBased 318 | RESULT_SIZE(SIZE_CODE(sizeof(long))) 319 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) 320 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long))) 321 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(char *))) 322}; 323 324#if USESROUTINEDESCRIPTORS 325typedef UniversalProcPtr AddrToStrUPP; 326 327#define NewAddrToStrProc(userRoutine) \ 328 (AddrToStrUPP) mzNewRoutineDescriptor(userRoutine, uppAddrToStrProcInfo, GetCurrentISA()) 329#define CallAddrToStrProc(userRoutine, selector, address, hostName) \ 330 CallUniversalProc(userRoutine, uppAddrToStrProcInfo, selector, address, hostName) 331#else 332typedef AddrToStrProcPtr AddrToStrUPP; 333 334#define NewAddrToStrProc(userRoutine) \ 335 (AddrToStrUPP)(userRoutine) 336#define CallAddrToStrProc(userRoutine, selector, address, hostName) \ 337 (*userRoutine)(selector, address, hostName) 338#endif 339 340 341pascal OSErr AddrToStr(addr, addrStr) 342unsigned long addr; 343char *addrStr; 344{ 345 if (dnr == nil) 346 /* resolver not loaded error */ 347 return(notOpenErr); 348 349 CallAddrToStrProc((AddrToStrUPP) dnr, ADDRTOSTR, addr, addrStr); 350 351 return(noErr); 352} 353 354 355 356typedef OSErr (*EnumCacheProcPtr)(long selector, long result, char* userData); 357 358enum { 359 uppEnumCacheProcInfo = kCStackBased 360 | RESULT_SIZE(SIZE_CODE(sizeof(long))) 361 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) 362 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) 363 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(char *))) 364}; 365 366#if USESROUTINEDESCRIPTORS 367typedef UniversalProcPtr EnumCacheUPP; 368 369#define NewEnumCacheProc(userRoutine) \ 370 (EnumCacheUPP) mzNewRoutineDescriptor(userRoutine, uppEnumCacheProcInfo, GetCurrentISA()) 371#define CallEnumCacheProc(userRoutine, selector, result, userData) \ 372 CallUniversalProc(userRoutine, uppEnumCacheProcInfo, selector, result, userData) 373#else 374typedef EnumCacheProcPtr EnumCacheUPP; 375 376#define NewEnumCacheProc(userRoutine) \ 377 (EnumCacheUPP)(userRoutine) 378#define CallEnumCacheProc(userRoutine, selector, result, userData) \ 379 (*userRoutine)(selector, result, userData) 380#endif 381 382 383 384pascal OSErr EnumCache(resultproc, userDataPtr) 385long resultproc; 386char *userDataPtr; 387{ 388 if (dnr == nil) 389 /* resolver not loaded error */ 390 return(notOpenErr); 391 392 return(CallEnumCacheProc((EnumCacheUPP) dnr, ENUMCACHE, resultproc, userDataPtr)); 393} 394 395 396 397typedef OSErr (*AddrToNameProcPtr)(long selector, unsigned long addr, struct hostInfo* rtnStruct, 398 long resultProc, char* userData); 399 400enum { 401 uppAddrToNameProcInfo = kCStackBased 402 | RESULT_SIZE(SIZE_CODE(sizeof(long))) 403 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) 404 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long))) 405 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(struct hostInfo *))) 406 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long))) 407 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(char *))) 408 409}; 410 411#if USESROUTINEDESCRIPTORS 412typedef UniversalProcPtr AddrToNameUPP; 413 414#define NewAddrToNameProc(userRoutine) \ 415 (AddrToNameUPP) mzNewRoutineDescriptor(userRoutine, uppAddrToNameProcInfo, GetCurrentISA()) 416#define CallAddrToNameProc(userRoutine, selector, addr, rtnStruct, resultProc, userData) \ 417 CallUniversalProc(userRoutine, uppAddrToNameProcInfo, selector, addr, rtnStruct, resultProc, userData) 418#else 419typedef AddrToNameProcPtr AddrToNameUPP; 420 421#define NewAddrToNameProc(userRoutine) \ 422 (AddrToNameUPP)(userRoutine) 423#define CallAddrToNameProc(userRoutine, selector, addr, rtnStruct, resultProc, userData) \ 424 (*userRoutine)(selector, addr, rtnStruct, resultProc, userData) 425#endif 426 427 428 429pascal OSErr AddrToName(addr, rtnStruct, resultproc, userDataPtr) 430unsigned long addr; 431struct hostInfo *rtnStruct; 432long resultproc; 433char *userDataPtr; 434{ 435 if (dnr == nil) 436 /* resolver not loaded error */ 437 return(notOpenErr); 438 439 return(CallAddrToNameProc((AddrToNameUPP) dnr, ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr)); 440} 441 442typedef long ResultUPP; 443enum { 444 uppResultProcInfo = kPascalStackBased 445 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(struct hostInfo*))) 446 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr))), 447 }; 448#define NewResultProc(proc) (ResultUPP)mzNewRoutineDescriptor((ProcPtr)proc, uppResultProcInfo, GetCurrentArchitecture()) 449