438 15 164KB
English Pages 8
H A CK I N G T H E R EG I S T R Y
Click & Retrieve Source
CODE!
Hacking the
Windows Registry BY K EI T H P LEA S
It’s a ju ngle ou t ther e, b u t w ith s ome gu id a nce, a n intrep id d evelop er ca n u nlock the s ecrets of the Win32 Regis tr y. f USER, Kernel, and GDI are the heart, brain, and eyes o f Windo ws, the registry wo uld be the memo ry—bo th lo ng and sho rt term. OK, maybe this metapho r is a bit weak, but the po int sho uld be o bvio us: the registry is a c ritic al c o mpo nent o f a well-func tio ning system and yo u’re no t go ing to get very far witho ut it. The registry is lightly do cumented and no t well understo o d. Pro gramming it can be similar to the o ld neuro lo gical technique o f zapping part o f the cerebral co rtex with an electro de and seeing what happens: the patient may remember a baseball game o r experience a war-related flashback. In Windo ws, yo u may enable a co o l new feature o r render yo ur system unbo o table. But it’s the thrill o f the hunt that makes it so exciting. After a brief intro ductio n to get o ur termino lo gy straight, I’ll skip the fundamentals o f the registry—MSDN wo uld be an ideal place to find this info rmatio n—and leap into advanced aspects. Alo ng the way I’ll no te a variety o f thing yo u c an take advantage o f immedi-
I
Ke ith Ple as is an inde pe nde nt de ve lo pe r, autho r, and traine r. He is the autho r o f the fo rthco ming bo o k, Visual Basic Tips & Tric ks, fro m Addiso n-We sle y. He can be re ache d o n Co mpu-Se rve at 71333,3014 ( fro m the Inte rne t: 71333.3014@co mpu-se rve .co m) .
22
ately: so me o f them are partic ular to the new Windo ws shell (first delivered o n Windo ws 95 but c urrently in beta o n Windo ws NT), so me wo rk o nly with NT (also kno wn as “Mic ro so ft’s re al o perating system”), and so me will wo rk fo r everybo dy. So , grab yo ur to o ls (primarily a c o py o f RegEdit) and prepare fo r an exc iting ro und o f hac king the registry. The registratio n database, c o mmo nly c alled the registry, c o ntains a substantial amo unt o f data abo ut the c o mputer and users. It inc ludes c o mputer data suc h as hardware, the OS, and installed applic atio ns, and user
USER also maps to a subkey). Keys beneath the ro o t are referenced by building a string key by co ncatenating each no de to gether, separated by backslashes. Eac h key also c o ntains data sto red in values: a key may have no values, a default value, o r any number o f named values in additio n to the default. The data in the values may be in a variety o f fo rms, tho ugh text and binary data types are by far the mo st c o mmo n. While key names and value names are never lo c alized, text data o ften is. Using the Windo ws 95 RegEdit utility sho ws yo u a muc h c o mpac ted view o f the registry inc luding the ro o t keys, several subkeys, a default (text) value, and a named (binary) value (see Figure 2). No te that Windo ws NT has a similar but slightly different struc ture: it o mits HKEY_ CURRENT_CONFIG and substitutes a so mewhat analo go us HKEY_PERFORMANCE_ DATA fo r HKEY_DYN_ DATA.
SPELUNKING THE REGISTRY
info rmatio n suc h as their deskto p settings and c usto mizatio n preferenc es. The registry sto res data in a hierarc hic ally struc tured tree. Eac h no de in the tree is c alled a key. Eac h key c an c o ntain additio nal keys c alled subkeys (see Figure 1). Keys are c o mpo sed o f printable c harac ters and c anno t inc lude bac kslashes (\) o r wildc ard c harac ters (* o r ?). Several predefined keys, represented with upperc ase wo rds separated by undersc o res, c an be ac c essed using numeric c o nstants. These keys are always “o pen,” so it’s no t necessary to use the RegOpen... func tio ns o n them. It’s impo rtant to no te that the ro o t key fo r mac hine info rmatio n HKEY_LOCAL_MACHINE(HKEY_CLASSES_ ROOT and HKEY_CURRENT_CONFIG map to subkeys) and the ro o t key fo r user info rmatio n is HKEY_USERS (HKEY_CURRENT_
MARCH 1996 Visua l Ba sic Progra mmer’s Journa l
A variety o f c o mmo n c o mpo nents c an be fo und in the registry, espec ially if they have anything to do with OLE. Here are so me examples so yo u’ll kno w what yo u’re lo o king at when yo u go spelunking with RegEdit. Creatable OLE c lasses, pro vided by OLE servers, must be in the registry. Eac h c lass is registered sep arately in the HKEY_CLASSES_ROOT\CLSID key under its CLSID and must, at minimum, have eno ugh info rmatio n fo r the OLE system to lo c ate and start the server. Fo r example, Ac c ess registers the Applic atio n o bjec t with the key name o n the left and the default value o n the right: {B54DCF20-5F9C-101BAF4E 00AA003F0F07} InprocHandler32 LocalServer32 ProgID
©1991–1996 Fawc ette Tec hnic al Public atio ns
Microsoft Access Database ole32.dll C:\MSOFFICE\ACCESS\MSACCESS.EXE Access.Application.7 http://www.windx.c o m
H A CK I N G T H E R EG I S T R Y {27395F85-0C0C-101B-A3C9-08002B2F49FB} 1.0 0 win32 C:\WINDOWS\SYSTEM\PICCLP32.OCX FLAGS HELPDIR
Microsoft PictureClip Control
2 C:\VB4
No te that the type lib rary itself c an b e sto red as a separate file o n disk ( typic ally with a TLB o r OLB extensio n) o r attac hed as a reso urc e to a DLL o r EXE. Bec ause OLE c o ntro ls are in fac t DLLs, their type lib raries are mo st o ften sto red with the c o ntro l itself. The HELPDIR key is no table bec ause it po ints to the fully qualified lo catio n fo r the acco mpanying WinHelp file co ntaining additio nal pro gramming do cumentatio n abo ut the co ntro l. This lo catio n can o bvio usly vary by installatio n and is typically determined when the co ntro l is first installed: if the WinHelp file is mo ved the link can o bvio usly be bro ken. Lic enses, suc h as tho se used b y OLE c o ntro ls, are also c o mmo nly sto red in the registry. They c an b e fo und under the HKEY_CLASSES_ROOT\Lic enses key, where yo u’ll also find the warning that “Co pying the keys may b e a vio latio n o f estab lished c o pyrights.” No kidding. Anyway, eac h lic ense is sto red under its o wn GUID. This example fro m my registry datab ase has b o th design and run keys ( with the key values c hanged, naturally) :
Rela ted Entries in the Regis try. Expande d ( Win95)
FIGURE 1 re gistry ke ys de pict ho w ro o t ke ys map to majo r subke ys fo r curre nt use r, classe s, and curre nt co nfiguratio n.
OLE c o ntro ls, being spec ialized in-pro c ess OLE servers, must be in the registry. If an OLE c o ntro l is referenc ed by an applic atio n but is no t in the registry, it c an auto register itself if the system c an lo c ate it by searc hing alo ng the no rmal DLL searc h path. OLE c o ntro ls are registered as c lasses and c an also be fo und in the HKEY_CLASSES_ROOT\CLSID key by referenc ing their CLSID. Fo r example, the Pic Clip c o ntro l that ships with VB4 has the fo llo wing registry entries:
{27395F85-0C0C-101B-A3C9-08002B2F49FB} Control InprocServer32 Insertable MiscStatus ProgIDPicClip.PictureClip ToolboxBitmap32 TypeLib Version
PicClip Control
abcdefghijklmnopqrstuvwxyzabcdefghij abcdefghijklmnopqrstuvwxyzabcdefghij
VB4 itself uses this technique: when it’s installed it merges the co ntents o f o ne o f the three REG files (fo r Standard, Professio nal, and Enterprise editio ns) into the registry. Finally, the registry co ntains info rmatio n abo ut re mo ted OLE se rve rs in bo th their lo cal and remo te co nfiguratio ns. Like the o ther OLE o bject described here, this VB4-created OLE Auto matio n server registers a Clerk c lass under its o wn GUID in the HKEY_CLASSES_ROOT\CLSID key. Of co urse, VB4 handles all the registratio n auto matically and it’s typically no t necessary to mo dify these entries directly. Running the Remote Automation Connection Manager (RacMgr32) utility included with VB4 Enterprise Edition adds additional keys for a remote machine name, RPC protocol, and RPC authentication level. When run locally, this particular class is registered as:
C:\WINDOWS\SYSTEM\PICCLP32.OCX
C:\WINDOWS\SYSTEM\PICCLP32.OCX, 1 {27395F85-0C0C-101B-A3C9-08002B2F49FB} 1.0
The Co ntro l key is used when dialo g bo xes like the OLE Insert Objec t dialo g o r VB4’s Custo m Co ntro ls dialo g is displayed with the Co ntro ls bo x c hec ked. Inpro c Server32 c o ntains the fully qualified path to the c o ntro l. ProgID contains the so-called “friendly” name, which can also be found in a separate key under HKEY_CLASSES_ROOT: this separate key contains a pointer back to the CLSID where all the information for the control is maintained. The Insertable key behaves similarly to the Control key, though it may be duplicated under the ProgID key for backward compatibility with OLE 1.0 servers. The type library fo r a c o ntro l is indic ated in the TypeLib key. Type libraries are sto red separately in the registry under their o wn GUIDs in the HKEY_CLASSES_ROOT\TypeLib key. The entries fo r the Pic Clip c o ntro l’s type library are: http://www.windx.c o m
{B54DCF20-5F9C-101B-AF4E-00AA003F0F07} Retail Runtime
{8435CD47-D6BE-11CE-A842-00AA00688747} _AuthenticationLevel _NetworkAddress _ProtocolSequence InprocHandler32 LocalServer32 ProgID TypeLib
2 NT ncacn_ip_tcp OLE32.DLL D:\PROJ\MSJ\CAR RENTAL\RENTAL OBJECTS.EXE RentalObjects.Clerk {8435CD4E-D6EB-11CE-A842-00AA00688747}
When the c lass is remo te, Rac Mgr32 c hanges the registratio n entries to :
{8435CD47-D6BE-11CE-A842-00AA00688747} _LocalServer32 AuthenticationLevel InprocHandler32 InprocServer32 NetworkAddress ProgID ProtocolSequence TypeLib
©1991–1996 Fawc ette Tec hnic al Public atio ns
D:\PROJ\MSJ\CAR RENTAL\RENTAL OBJECTS.EXE 2 OLE32.DLL C:\WINDOWS\SYSTEM\autprx32.dll NT RentalObjects.Clerk ncacn_ip_tcp {8435CD4E-D6EB-11CE-A842-00AA00688747}
Visua l Ba sic Progra mmer’s Journa l MARCH 1996
23
H A CK I N G T H E R EG I S T R Y
Text Value
Keys
Subkeys Binary Value
Keys to the Wind ow s Regis try. The hie rarchical structure o f the re gistry co nsists o f ke ys and subke ys. The asso ciate d value s
FIGURE 2 fo r e ach ke y can be name d ( te xt) o r a no n-string data type ( binary) . No tic e ho w the Lo c alServer32 key gets renamed ( ac tually, keys c anno t b e renamed, so it is destro yed and re-c reated) and an additio nal Inpro c Server32 key is c reated. This new key po ints to the remo te auto matio n pro xy o n the lo c al mac hine, initiating a c o nversatio n with the AutMgr utility running o n the remo te mac hine. Of co urse, yo u’ll never want to to uch these registratio n entries directly. In additio n to using RacMgr32, we can also call the RacReg OLE Auto matio n server in co de to examine and change server settings. To do so add a reference to the RacReg32.DLL, create a RacReg.RegClass o bject, and use the GetAuto ServerSettings functio n and SetAuto ServerSettings metho d. Unfo rtunately, the do c umentatio n fo r these func tio ns is a little o bsc ure: it’s o nly fo und in the ReadMe file that ships with VB4. But it’s pretty o bvio us ho w the Rac Reg32 server reads/writes the registry settings sho wn in this func tio n pro to type: object.SetAutoServerSettings (Remote, [ProgID], [CLSID], _ [ServerName], [Protocol], [Authentication])
A side benefit o f using the Rac Reg.RegClass o bjec t is that Mic ro so ft’s VB gro up pro mises that yo ur c o de will be upwardly c o mpatible with future versio ns o f VB, whic h will suppo rt true Netwo rked OLE: they’ll do the wo rk o f enc apsulating the c hanges so that yo u do n’t have to c hange yo ur c o de.
USING REGISTRY FUNCTIONS The Win32 API pro vides a func tio n gro up o f 26 APIs, many o f them with b o th “A” ( ANSI) and “W” ( Wide, o r Unic o de) versio ns, fo r wo rking with the registry. Five o f the 26 APIs are
24
MARCH 1996 Visua l Ba sic Progra mmer’s Journa l
pro vided fo r b ac kward c o mpatib ility o nly and sho uldn’t b e used ( the c o rrespo nding ...Ex func tio ns, whic h suppo rt named values and ac c ess to keys o ther than HKEY_CLASSES_ROOT, sho uld b e used instead) . Rather than to rture yo u with a c o mplete list o f the APIs, I’ll po int yo u to a c o uple o f useful samples that highlight their implementatio n suc h as the RegTo o l sample that ships o n the VB4 disc . The RegTo o l sample is buried do wn in the \To o ls\ Dataex32\So urc e\Regto o l subdirec to ry and has a reusable c lass with ro utines fo r c reating, updating, and deleting keys. Unfo rtunately, while it c an read bo th string and numeric (dwo rd) data, it c an o nly write strings. A much better example can be found in the file REGVB4.ZIP in the Magazine Library of the VBPJ Forum on CompuServe. Written by Don Bradner, VBPJ Fo rum Section Leader of the “32-Bit Bucket,” REGVB4 is a handy VB4 version of RegEdit that has well-commented source c o de for reading and writing both string and numeric values. Several o f the registry func tio ns deserve a bit mo re c o mment. While we do no t yet have built-in suppo rt fo r a distributed registry (where part o r all o f yo ur registry is sto red o n ano ther mac hine), the RegCo nnec tRegistry func tio n c an be used pro grammatic ally to c o nnec t to remo te registries and get/ set values fro m their registries. They c an c o nnec t o nly thro ugh the ro o t keys (HKEY_LOCAL_MACHINE and HKEY_USERS), but bec aus e o f th e s ub ke y m ap p ings to HKEY_ CURRENT_ USER, HKEY_CLASSES_ROOT, and HKEY_CURRENT_CONFIG this isn’t a majo r limitatio n. There are also a few differences between the Win95 and WinNT implementatio ns o f the registry functio ns. Of co urse, Win95 kno ws no thing abo ut security, so Get/SetKeySecurity aren’t implemented
©1991–1996 Fawc ette Tec hnic al Public atio ns
http://www.windx.c o m
H A CK I N G T H E R EG I S T R Y o n that platfo rm. Also , while Win95 do es implement QueryInfo Key, it do esn’t track the last write time, so do n’t be surprised when the FILETIME structure co mes up empty. Ano ther thing to watc h o ut fo r, particularly if you develop under Win95, is that RegDeleteKey on that platform deletes key and descendants, whereas on NT it can only delete keys that have no subkeys. Because o f its architecture, Win95 has very limited suppo rt fo r kernel synchronization objects, and thus RegNotifyChangeKeyValue is no t sup p o rte d at all. Win95 also d o e sn’ t imp le me nt RegResto reKey, which can be wo rked aro und tedio usly by writing co de to re-create the keys o r, much easier, by using a REGEDIT4 file. Interestingly, RegQueryMultipleValues is only implemented on Win95 (though its primary value appears to be as a coding shortcut). Finally, if you must store Unicode data in the Win95 registry you must store it as REG_BINARY, because Win95 is an ANSI system. It’s also wo rth po inting o ut that VB4 inc ludes built-in func tio ns fo r wo rking with the registry, tho ugh they o nly wo rk with info rmatio n fro m a spec ific lo c atio n in the registry: HKEY_CURRENT_USERS\Software\VB and VBA Program _ Settings\
Adding the TXT File Typ e to the Exp lorer. This vie w o f
I’ve seen a number o f peo ple experienc e pro blems with the built-in VB func tio ns.GetSetting and GetAllSettings are func tio ns, but SaveSetting and DeleteSetting are statements and thus do n’t use parentheses. While SaveSetting and DeleteSetting were o riginally spec ified as func tio ns, later they bec ame statements.
IM PORT DATA INTO THE REGISTRY It’s c o mmo n to use registratio n (REG) files fo r impo rting data into the registry. REG files have two fo rmats: REGEDIT and http://www.windx.c o m
FIGURE 3 the Ne w me nu in the Win95 e xplo re r is fairly typical,
e xce pt that by using the re gistry, I adde d the TXT file type to the me nu. Se le cting it launche s No te pad, the file asso ciate d with TXT file s.
REGEDIT4. REGEDIT4 was intro duc ed to deal with named values. RegEdit c an run fro m the c o mmand line, but in this c o nfiguratio n, it will no t be able to lo ad REGEDIT4 files. If yo u’re wo rking o n NT, yo u sho uld use the RegIni utility fro m the NT Reso urc e Kit. CONTINUED ON PAGE 30.
©1991–1996 Fawc ette Tec hnic al Public atio ns
Visua l Ba sic Progra mmer’s Journa l MARCH 1996
25
H A CK I N G T H E R EG I S T R Y
Ad d ing the Tes t VB Find er to the Find Menu in Exp lo rer. The re gistry structure fo r dynamically adde d Find ite ms illustrate s
FIGURE 4 ho w simple it is to add ite ms to the me nu. A mo difie d Find Me nu in the ne w she ll’s Explo re r sho w an e ntry adde d by MSN as we ll as two custo m e ntrie s de scribe d he re . It’s just as e asy to add an e ntry fo r so me thing like Yaho o fo r finding file s o n the Inte rne t.
CONTINUED FROM PAGE 26. This sho ws the co ntents o f a trivial REG file using the o ld fo rmat: REGEDIT HKEY_CLASSES_ROOT\.txt = txtfile
And, this sho ws this new fo rmat (with a named value): REGEDIT4 [HKEY_CLASSES_ROOT\.txt] @="txtfile" "Content Type"="text/plain"
If yo u distribute a REG file with yo ur applic atio n, be aware that Setup To o lkit has so mewhat limited suppo rt fo r this. Yo u c an add a REG file with the Add Files butto n and the Setup To o lkit will register tho se keys o n the user’s mac hine. Ho wever, yo u are limited to embedding relative paths and there’s no auto mated suppo rt fo r uninstalling the REG file entries. If yo u’ve been fo llo wing alo ng o n yo ur mac hine, yo ur registry might be getting a little wo nky. It’s no t unc o mmo n fo r yo ur registry to get whac ked: hac king aro und manually just tends to ac c elerate this pro c ess. Eventually, yo u’re go ing to want to use the little-kno wn RegClean utility (16- and 32-bit) that ships with VB4 and is lo c ated in the \To o ls\PSS subdirec to ry. It c an c o rrec t a number o f these pro blems in yo ur registry: • Mismatc hed GUID in TypeLib. • Missing TypeLib GUID. • Missing CLSID fo r Pro gID. • Useless NumMetho ds o r BaseInterfac e keys.
26
MARCH 1996 Visua l Ba sic Progra mmer’s Journa l
• Invalid Pro gID key. • Missing OLE key. • Wro ng value fo r OLE key. • Missing file. • Empty subkey. • Co nflic ting lo c al/ remo te keys. • Impro per Inpro c Server registratio n. • Server isn’t AUTPRX16.DLL/ AUTPRX32.DLL. • Differing server paths. • Missing Inpro c Server key. RegClean also gives yo u the o ptio n o f c reating a pending c hange file o r just letting it rip and make the c hanges fo r yo u (guess whic h o ne I c ho se).
EXTENDING THE NEW SHELL If yo u’ve selec ted New fro m the File menu within the Windo ws 95 Explo rer, after what seems like an ino rdinate delay yo u’ve seen a c asc ading menu (see Figure 3). The shell is searc hing thro ugh the registry lo o king fo r valid file extensio ns (tho se beginning with “.”) that have a subkey o f ShellNew. Eac h time it finds o ne, it reads the value in the extensio n’s key to determine the Pro gID, lo o ks up the Pro gID, and adds the value o f that key to the menu. Fo r example, to add the TXT item to the menu sho wn in Figure 3, I added the ShellNew key to the CLSID key fo r “.txt” files:
HKEY_CLASSES_ROOT\.txt = txtfile ShellNew CONTINUED ON PAGE 34.
©1991–1996 Fawc ette Tec hnic al Public atio ns
http://www.windx.c o m
H A CK I N G T H E R EG I S T R Y HKEY_CLASSS_ROOT\. = "txtfile" Dim CRLF As String Dim QT As String Dim sFile As String For x = 1 To Len(txtFile) 'Double \\ If Mid$(txtFile, x, 1) = "\" Then sFile = _ sFile & "\" sFile = sFile & Mid$(txtFile, x, 1) Next x CRLF = Chr$(13) & Chr$(10) QT = Chr$(34) txtScript = "" txtScript = "REGEDIT4" txtScript = txtScript & CRLF & "[HKEY_LOCAL_MACHINE\_ SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\_ FindExtensions\Static\" & txtShort & "]" txtScript = txtScript & CRLF & "@=" & QT & _ txtGUID & QT txtScript = txtScript & CRLF & "[HKEY_LOCAL_MACHINE\_ SOFTWARE\Microsoft\Windows\CurrentVersion\_ explorer\FindExtensions\Static\" & txtShort & _ "\0]" txtScript = txtScript & CRLF & "@=" & QT & _ txtDescription & QT txtScript = txtScript & CRLF & "[HKEY_LOCAL_MACHINE\_ SOFTWARE\Microsoft\Windows\CurrentVersion\_ explorer\FindExtensions\Static\" & txtShort & _ "\0\DefaultIcon]" txtScript = txtScript & CRLF & "@=" & QT & sFile & _ ",0" & QT txtScript = txtScript & CRLF txtScript = txtScript & CRLF & _ "[HKEY_CLASSES_ROOT\CLSID\" _ & txtGUID & "\FindCmd]" txtScript = txtScript & CRLF & "@=" & QT & sFile & QT txtScript = txtScript & CRLF & _ "[HKEY_CLASSES_ROOT\CLSID\" _ & txtGUID & "\InprocServer32]" txtScript = txtScript & CRLF & "@=" & QT & _ "FindExt.dll" & QT txtScript = txtScript & CRLF & QT & _ "ThreadingModel" & QT _ & "=" & QT & "Apartment" & QT txtScript = txtScript & CRLF
REGEDIT4 Scrip t Genera tion. This script is pre tty
LISTING 1 standard string manipulatio n co de , with o ne e xce ptio n. No te the re quire d do uble d backslashe s and trailing blank line .
whic h, when ac c essed by the shell, was translated into the:
HKEY_CLASSES_ROOT\txtfile = TXT Of c o urse, the po int o f this isn’t that yo u c an launc h No tepad ( tho ugh that is so mewhat useful) , b ut that yo u add yo ur pro gram to the New item fro m yo ur users File menu with very little effo rt. The shell c an be extended in many o ther ways. Fo r example, yo u c an add a destinatio n applic atio n to the Send To menu fo r all Explo rer items by plac ing a sho rtc ut to the destinatio n applic atio n in the \Windo ws\SendTo fo lder. I suggest yo u c reate a sho rtc ut in the \Windo ws\SendTo direc to ry fo r RegSvr32.EXE. Hec k, yo u do n’t even have to run RegEdit to do this o ne. Yo u may have c lic ked o n files in the shell that do n’t have any extensio n: the resulting dialo g is anno ying b ut at least yo u c an asso c iate the file with a partic ular applic atio n. Unfo rtunately, that asso c iatio n do esn’t “stic k” and yo u have to do this every time. Files witho ut an extensio n are o f c lass “.” and yo u must manually add this type to the registry. Yo u c an either add a single key that po ints to whatever ( fo r instanc e) a “txtfile” might b e: http://www.windx.c o m
o r yo u c an enter yo ur o wn c lass as in this example:
HKEY_CLASSS_ROOT\. = "none" HKEY_CLASSS_ROOT\none\DefaultIcon = "notepad,1" HKEY_CLASSS_ROOT\none\shell\open\command = “notepad.exe "%1."" If yo u just want to add a single menu c o mmand to the c o ntext menu o f a spec ific file type, yo u c an use a similar tec hnique metho d: these two entries will add an Edit menu item to VB pro jec t (VBP) files and lo ad them into No tepad:
HKEY_CLASSS_ROOT\VisualBasic.Project\shell\Edit = "" HKEY_CLASSS_ROOT\VisualBasic.Project\shell\Edit\command = "notepad.exe "%1.""
EXTENDING THE FIND M ENU The new shell c an be extended in a number o f ways using, no t surprisingly, a mec hanism c alled shell extensio ns. Shell extensio ns are implemented as spec ialized DLLs that c reate OLE COM o bjec ts and suppo rt spec ific OLE interfac es. One example is the built-in “Files o r Fo lders...” and “Co mputer...” menu items fo und o n the Find submenu. While it’s po ssible to add to this menu, just as MSN do es with the “On The Mic ro so ft Netwo rk...” item, shell extensio ns c anno t c urrently be written in VB. Fo rtunately, Jeff Ric hter has written a c usto m FindExt.DLL that enc apsulates the nec essary func tio nality and allo ws attac hment o f any pro gram to the Find submenu (see Figure 4). Yo u generate c usto m CLSIDs that po int to this DLL: when o ne is invo ked, the DLL lo o ks up the asso c iated c o mmand line and exec utes it. This c o mpiled DLL is inc luded with the sample c o de fo r this artic le available o n VBPJ’s Develo pment Exc hange o n Co mpuServe (GO WINDX), The Mic ro so ft Netwo rk (GO WINDX) and the Wo rld Wide Web (http:/ / www.windx.c o m) and c an be freely distributed. Ric hter will be writing abo ut and publishing the so urc e c o de later this year. Extensio ns to the Find submenu are sto red in the registry, b urie d in th e HKEY_ LOCAL_ MACHINE\SOFTWARE\ Mic r o s o ft \W in d o w s \Cu r r e n t Ve r s io n \e x p lo r e r \ FindExtensio ns subkey. Extensio ns sto red at that level are lo aded auto matic ally when the Explo rer is first lo aded (no rmally the shell bo o ts when Windo ws 95 is first lo aded). The Static subkey beneath that c o ntains extensio ns that are lo aded dynamic ally: they are invo ked when the user selec ts the item o n the Find submenu. This is where yo u sho uld put yo ur c usto m find utilities. To do so yo u need to c reate three additio nal nested subkeys: the extensio n that po ints to the CLSID o f the InPro c server, the menu text, and the menu ic o n. The first item to add is the extensio n that po ints to the CLSID o f the InPro c OLE server. The name o f this key (InetFind, MSNFind, and VBFind in the figure) is unimpo rtant: Windo ws never displays it and the submenu items are ac tually drawn fro m the registry in the o rder they were added, no t alphabetic ally. The value o f this key is the text versio n o f a CLSID that po ints to FindExt.DLL, in this c ase. Next, add the menu text itself (inc luding an ac c elerato r key if desired). The name o f this key must be “0.” Finally, add the ic o n to be displayed in the menu, whic h has a value that inc ludes the file name o f the exec utable and the index o f the ic o n (typic ally zero ) to be used. The name o f this key must be “DefaultIc o n.” To see the new menu item, it’s nec essary to restart the Explo rer. Yo u c an either restart Windo ws 95, whic h is slo w and inc o nvenient, partic ularly if yo u have multiple applic atio ns o pen, o r yo u c an shut do wn and restart the shell. To shut do wn the shell, c ho o se “Shutdo wn” fro m the Start menu and, when yo u see the “Shut Do wn Windo ws” dialo g bo x, ho ld do wn the CONTINUED ON PAGE 38.
©1991–1996 Fawc ette Tec hnic al Public atio ns
Visua l Ba sic Progra mmer’s Journa l MARCH 1996
27
H A CK I N G T H E R EG I S T R Y The first step in using this utility is to generate a new CLSID, which is equivalent to a GUID (fo r “Glo bally Unique ID” in Micro so ft termino lo gy) o r UUID (fo r “Universally Unique ID,” in DCE/RPC termino lo gy). VB c reates GUIDs fo r us auto matic ally when we c reate OLE Servers, and the GUIDGen utility inc luded in the Win32 SDK c an b e used to generate them manually. Anyway, I want to c reate a CLSID pro grammatic ally so I need to c reate a GUID struc ture and fill it in b y c alling the OLE func tio n Co CreateGuid, whic h in turn c alls the RPC func tio n UuidCreate. The Win32 d o c umentatio n states that Uuid Create is no t imp lemented o n Wind o ws 95, b ut that isn’ t true: it c an b e fo und in RPCRT4.DLL. The Win32 header files give this structure fo r a GUID:
VB4 Declare Function RegNotifyChangeKeyValue Lib _ "advapi32.dll" _ (ByVal hKey As Long, ByVal bWatchSubtree As Long, _ ByVal dwNotifyFilter As Long, ByVal hEvent As Long, _ ByVal fAsynchronus As Long) As Long Declare Function WaitForSingleObject Lib "kernel32" _ (ByVal hHandle As Long, ByVal dwMilliseconds As _ Long) As Long Declare Function CreateEvent Lib "kernel32" Alias _ "CreateEventA" (lpEventAttributes As Long, ByVal _ bManualReset As Long, ByVal bInitialState As Long, _ ByVal lpName As String) As Long Declare Function CloseHandle Lib "kernel32" (ByVal _ hObject As Long) As Long Public Const HKEY_CLASSES_ROOT = &H80000000 Public Const REG_NOTIFY_CHANGE_ATTRIBUTES = &H2 Public Const REG_NOTIFY_CHANGE_LAST_SET = &H4 Public Const REG_NOTIFY_CHANGE_NAME = &H1 Public Const REG_NOTIFY_CHANGE_SECURITY = &H8
typedef struct _GUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[8]; } GUID;
Private Sub cmdRegistry_Click() Dim lChange As Long mhEvent = CreateEvent(0&, False, False, vbNullString) lChange = RegNotifyChangeKeyValue_ (HKEY_CLASSES_ROOT, True, _ REG_NOTIFY_CHANGE_NAME, mhEvent, True) tmrRegistry.Enabled = True Me.Caption = "Waiting for registry change..."
// size is 16
whic h I translated into this VB c o de: Type tGUID P1 As Long P2 As Integer P3 As Integer P4 As Byte P5 As Byte P6 As Byte P7 As Byte P8 As Byte P9 As Byte P10 As Byte P11 As Byte End Type
End Sub Private Sub tmrRegistry_Timer() Static lSignal As Long Static lResult As Long lSignal = WaitForSingleObject(mhEvent, 0&) If lSignal = 0 Then Me.Caption = "Registry Changed" tmeRegistry.Enabled = False lResult = CloseHandle(mhEvent) End If End Sub
Decla r a tio ns a nd Co d e fo r Ha nd ling Regis try
LISTING 2 Cha nge Notifica tion.The cmdRe gistry_Click subro utine
cre ate s the e ve nt o bje ct, passe s its handle to the syste m signalling whe n the re gistry change s, and starts the po lling time r. De tails abo ut Re gistry Change No tificatio n me ssage s are sho wn in Table 1.
The Co CreateGuid dec laratio n was pretty o bvio us: Declare Function CoCreateGuid Lib _ "OLE32.DLL" (guid As tGUID) As Long
Calling it is dead simple: Ctrl-Alt-Shift key c o mbinatio n and c lic k o n the “No ” butto n. This leaves yo u in so mething like the o ld shell, where pressing CtrlEsc ape brings up the Task Manager, fro m whic h yo u c an selec t “Run” fro m the File menu and restart Explo rer. Altho ugh the menu item is visible at this po int, it wo n’t ac tually do anything. To make it wo rk, yo u must add the CLSID to the HKEY_CLASSES_ROOT\CLSID key and c reate a c o uple o f additio nal subkeys: the CLSID o f the OLE InPro c server referenc ed by the Find extensio n, the c o mmand line to be exec uted by FindExt.DLL, whic h must be sto red under the FindCmd key, and finally the Inpro c Server32 key with two values. The first, whic h is the default, c o ntains the path (if appro priate) and file name o f the FindExt.DLL, whic h will typic ally be lo c ated in the \Windo ws\System subdirec to ry. The seco nd key, “ThreadingMo del,” sho uld be set to “Apartment” because the FindExt.DLL uses that mechanism and is, in fact, thread safe. The threading mo del applies o nly to OLE Servers that are lo ading in pro cess. The steps I’ve o utlined are a bit tedio us, yet they must be carried o ut exactly fo r this to wo rk pro perly. To ease the pro cedure, I wro te a small Finder Installatio n utility that auto mates the who le pro cess (available fo r do wnlo ad fro m the o nline services described elsewhere in this article).
28
MARCH 1996 Visua l Ba sic Progra mmer’s Journa l
Dim tmp As tGUID lRet = CoCreateGuid(tmp)
Unfo rtunately, the GUID yo u end up with is binary. Yo u need a s tring in th is fo rm at: “ { xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx}”. The Win32 API do es pro vide a UuidTo String func tio n lo c ated in RPCRT4.DLL and the Win32 SDK header files pro vides this pro to type: UuidToStringA ( IN UUID __RPC_FAR * Uuid, OUT unsigned char __RPC_FAR * __RPC_FAR _ * StringUuid );
But, it turns o ut that this func tio n isn’t c allable fro m VB. Ho wever, ano ther func tio n, StringFro mGUID2, gets us o n the right trac k using this dec laratio n: Declare Function StringFromGUID2 Lib _ "OLE32.DLL" (guid As tGUID, lpszString As _ Byte, lMax As Long) As Long
©1991–1996 Fawc ette Tec hnic al Public atio ns
http://www.windx.c o m
H A CK I N G T H E R EG I S T R Y
MESSAGE
DESCRIPTION
REG_ NOTIFY_ CHANGE_ NAME
Changes to key names that occur in the specified key or in the specified key and its subkeys cause a change notification. This includes key creations and deletions. Attribute changes that occur in a key or in a key and its subkeys cause a change notification. Changes to the last write time that occur in a key or in a key and its subkeys cause a change notification. Security-descriptor changes that occur in a key or in a key and its subkeys cause a change notification.
REG_ NOTIFY_ CHANGE_ ATTRIBUTES REG_ NOTIFY_ CHANGE_ LAST_ SET
REG_ NOTIFY_ CHANGE_ SECURITY
TABLE 1
Wha t’s Cha nged? Re gistry change no tificatio n me ssage s,
and the ir de scriptio ns. Be aware that so me me ssage s that e xist o n Windo ws NT are n’t suppo rte d by Windo ws 95.
Calling this func tio n and putting the result into the Text c o ntro l is a piec e o f c ake: Dim bBuff(256) As Byte lRet2 = StringFromGUID2(tmp, bBuff(0), 256&) txtGUID = bBuff
These three lines of code are doing a lot. The contents of the bBuff byte array are actually a Unicode string. If you examine it in detail, you’ll see that every element contains the ASCII value of a character that you want in the string version. Assigning the contents of the buffer to a string (or, in this case, the text property of a Text control) converts it correctly because VB4 strings are internally Unicode. The sec o nd and third steps are to simply fill in the extensio n key name (whic h is no t used), menu text, and c o mplete c o mmand line that we wish to exec ute. The fo urth step is to generate a c o mplete REGEDIT4 sc ript that c o ntains all o f the entries in the appro priate fo rmat. This is straightfo rward VB string manipulatio n c o de (see Listing 1) with these c aveats: any key value c o ntaining a bac kslash c harac ter must be do ubled and the sc ript must have a blank line at the end fo r the previo us line to be registered c o rrec tly. The last step is to c o py this sc ript into a REG file and exec ute it fro m the shell. Again, bec ause yo u c reate yo ur o wn CLSID, yo u c an have any number o f Find extensio ns o n a system witho ut wo rrying abo ut c o lliding with o ne written and installed by so meo ne else. Bec ause the FindExt.DLL is internally c alling the new Win32 ShellExec ute func tio n, yo u c an even substitute the exec utable file name with so mething like this: http://www.yahoo.com
Yo u might asso c iate this with the menu desc riptio n “On The &Internet... .” Cho o sing this auto matic ally brings up the Internet Explo rer, lo gs yo u o n to the Internet, and take yo u to the Yaho o finder. Other ideas fo r Find extensio ns might inc lude a c o mpany-wide address bo o k, a sho rtc ut to MSDN, o r virtually anything else that makes sense to yo u.
DIFFERENCES BETW EEN NT AND 95 As develo pers are all to o painfully aware, there are majo r differenc es between the Windo ws 95 and Windo ws NT platfo rms. So me o f these differenc es will disappear o ver time: the NT Shell Update Release (SUR) will add the new shell, TAPI suppo rt, and so o n, while so me o f the mo st glaring differenc es, like Windo ws 95’s lac k o f sec urity, will remain. One o f the gray areas is suppo rt fo r theWin32 Kernel sync hro nizatio n o bjec ts: while suppo rt fo r the file c hange no tific atio ns is suppo rted thro ugh the FindXXXChangeNo tific atio n family o f APIs o n bo th http://www.windx.c o m
platfo rms, suppo rt fo r registry c hange no tific atio ns (thro ugh RegNo tifyChangeKeyValue) is suppo rted o nly o n NT. While a full discussio n o f kernel synchro nizatio n o bjects—such as mailslo ts, pro cesses, threads, mutexes, events, semapho res, file handles, file mappings, named pipes—will have to wait until ano ther time, I’ll co ver o nly registry synchro nizatio n fo r no w. Kernel event o bjec ts c an exist in either a signaled o r no tsignaled state. Basic ally, we c reate an event o bjec t, tell the system to signal that o bjec t when the registry c hanges, and wait fo r the o bjec t to get signaled. No rmally this is do ne sync hro no usly by suspending the c alling thread until the signal o c c urs. Unfo rtunately, bec ause VB apps c an c urrently use o nly a single thread, this wo uld have the effec t o f hanging the entire app until the c hange o c c urs. Freezing an applic atio n is c o nsidered to be sub-o ptimal fro m an implementatio n standpo int (users generally do n’t like this), so I pro grammed aro und this limitatio n using a Timer and perio dic ally c hec king the state o f the event. While po lling is usually a sign o f a bad applic atio n arc hitec ture, in this c ase there’s no o ther c ho ic e. To illustrate this, I c reated a small testing applic atio n that’s e asy to fo llo w ( se e Listing 2) . The c o d e starts in the c mdRegistry_Clic k subro utine, whic h c reates the event o bjec t, passes its handle to the system to get signaled when the registry c hange s, and starts the p o lling time r. The time r c alls WaitFo rSingleObjec t (with a time o f 0 millisec o nds) and returns immediately. When the event gets signaled, the timer is disabled and the event o bjec t is destro yed by c lo sing its handle. This partic ular example lo o ks fo r c hanges to key names at the ro o t level o f HKEY_CLASSES_ROOT and inc ludes subkeys: it’s pro bably the mo st useful, altho ugh yo u may want to examine the o ther o ptio ns fro m the Win32 SDK (see Table 1). As a final reminder, sinc e the RegNo tifyChangeKeyValue func tio n is implemented o nly o n Windo ws NT, this tester wo n’t do anything o n Windo ws 95. Here are so me useful tips. First, any lo ng file names sto red in the registry sho uld be enc lo sed in quo tes, like this:
shell\open\command = “C:\Program Files\My Accessories\WinWord.Exe” %1 Alternately, the short file name could be stored so it will work on all systems. An example of this is the system-supplied Find utility that supplies the “Files or Folders...” and “Computer...” menu items:
C:\Progra~1\TheMic~1\findstub.dll While type and size o f data yo u c an sto re in the registry is relatively unlimited, in general yo u sho uld no t sto re frequently ac c essed data in the registry. Registry ac c ess is muc h slo wer than shared memo ry and even slo wer than file ac c ess. Yo u sho uld also be aware that named values c o nsume less spac e than keys c o nsume. Yo u might also c o nsider pac king data to gether into a struc ture and sto ring the entire struc ture as a single binary value. If yo ur applic atio n is adding mo re than a c o uple o f kilo bytes to the registry, c o nsider sto ring a po inter to that data and lo c ating it elsewhere, either as a file o r perhaps as a type library. Also , while it’s c ertainly po ssible, Mic ro so ft stro ngly enc o urages develo pers no t to sto re binary, exec utable pro grams in the registry. If yo u’re still interested in the registry and are lo o king fo r a plac e to jump in where yo u’re likely to see familiar stuff, I’ll leave yo u with these keys as “suggested reading:”
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\SessionManager\KnownDLLs HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping HKEY_LOCAL_MACHINE\\SOFTWARE\Microsoft\Windows\CurrentVersion\AppPaths HKEY_LOCAL_MACHINE\\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
©1991–1996 Fawc ette Tec hnic al Public atio ns
Visua l Ba sic Progra mmer’s Journa l MARCH 1996
29