ÿØÿà JFIF    ÿÛ „ !.%+&8&+/1555$;@;4?.451 4,$,44444444444414444444444444444444444444444444444444ÿÀ  á á" ÿÄ     ÿÄ ?    !1AQaq"2‘¡±ÁðBRbrÑá#‚’¢²3S CñÿÄ   ÿÄ !    !1QAa‘2ÿÚ   ? 5˜Z¯V¦cø)›t/? z¨±>Õ5€¶‹Á¤·¼z¼Ü¬+ñ®v¤¨_ˆR­BFn©—˜ý®ç̝P8gýt·ÉSTŦˆìät?þé¼íìN/Þa)ì–í6ô… Ï¿øÃj´¿KÇü]ÿ ªô¹-eKànëÕHTx}ýSÜ›ÿ ”7Ø×&µ<¦  ¥ÑO¶[Ù¯ä¨ÞÃÿ PZ-¬;#õ|•oaÿ ©CìÞz3˜öː/¤­ñTûIØ}š^ mÓ%ªxˆ¥ÉŸu=Z+ISe¿45™¼u;ú&WØ÷€æßQ™®{|íx*TC“#ZŠìZ§²‹ 6pv…³¿¡äª*áZÐ%ÒOáˆo"x«OHk w±æ+¬V(kMúŸ5Vö«$ ÁrÏbàb57/luR ¸ÑÛj Òµì`Мq­û žICÀÊ•©4€Âcà¨Ï€O´<èÐ:›ù(Ë^L8þ‘ÍÌ#¸Ð_Ì©ÙK(Öz 4¬û+¸;ü’V’84‘¬ÃŽ:[â‡ÔÌáõp¢~§ªlæ£ö{®G>J¼"°‡7¯ÆÉèßû ‹É‹§ÁòÃýâßî ^ƾÙõ‹×óH#«LP½ïX=xÑÍ$|W?•~• îëÔ©ª‹ {ÝT…Kÿ ”hûâá)J*ö˜–ÔU;iÇ€/ ÆþjóZ\ýwØ=Ìm ºèËL9 ýèÆð/¨’¥öo=nË.%Îì ŽÕ¯È|{Oj²ƒE6e/ßdÄõ²Ìâ1O®ò×TsəԸhOMýíMˆ¿¼H˜l²,7Â¥#MF/Úf°Ö½± ¸–dr‹NýÊ íjqx{œÉ ä-È ¦ øÄër¨q°ð †nцýÑÄÆ’mä…n<0È™;ÁÝá¯ÁZƒ7FÀmì­ É&9ˆîéi¶ùN§Y• ÃZãAâ?•‡©‰ , ó¾IŸŠc1 4â&y­&pŠ­6;M À 0¹qç»p.á …ŸÅáK@%6·y6ƒ‰3?”úºŽ‰éX5ªPT §µ!=Mž«Ú½‹ÅgÂSâÉaþÓoö–¯ÁÔìR>5éÿ üs¶ÆUcÌ kÇR ]ÿ ù¬¼«VŽ;Â|‡~¢¦”ÏŰæ {L™Õ°Óv¹ò¸írޡעCÃ!íVÕ {¶»sŒNPg/ "uÕbkm²“$ďå¿é¹§°½æz¯6 †s¿!s–wÚÝ“™Œ °.ûj>·+™Òa…©Œ&rÝÎtÛë긪Ît’LAVp%c Úý[ÄzJ¾ÇàXXç@˜ó<êL]·T˜¾¥1Ó©V‡g´æ½¦Ý@¹óø!_@´ÞâSÁ —S3™•& ]@JHÚý©ZŽ €×æÔr»Áf!‡yÞ4Mv*èÓã_{‘åóUuљØ«Oïé*®EvÑ Œ÷‡U \"㪒ÍK+À 4“M¡ï:0¥5í!'<@î´”>Ç»&Z–ïCCV˜Ì5Šo&îhè.žû |ÓK©h$s6KìŒëã)¹hI¦GïOåóI;ììü#É$Š0…Ææ¥TØ.5­¾gn´ “ÂÖ\:hœ89G)J@„}œ:’Ò{/Š"¦_Æ×7Æ3VÇŠÊa]ÚŒÙ€Ä–=®uÁßâACZƒ§§£ Qnâ:«,×{tyø¬iÛcœÜÄ€H½ÄÍCk´÷šß .W'b¤Íåh]÷€=,Žv×cÚEÚHXJX¶îo¨FÒtèöŸ>ªª6[J®Fµ£sGÁeqõfe\íjÒÐïÄÐGˆe1Ø‹.Ø”‘Ëuø Y­ˆÜ ŽG|zùªüMpDnQWÄ”%JŠ™)â*p@Örš«ÕT2Ð%ˆG#ª„ ·¤!°ŸOTÂT¸aÚ%4&h™LµšØüÐ.F¿²ÐÞ_Ç‚¾ÅÃaÜ÷09Æ q€öy˜v‡85õN÷]¬äѼóS{°_MެúÔ#°Ç¸0åÞè2ëôPcvÆw9®ií1Ä8F™˜à‰´+‰Ik1òÝ7“Ñ×ÒsÝ\x‚h`ÞÑ`ó"|µEcý£n˜h`}GÞ !±ù²Ápü²ß6 0ïi󜵩SÈÇ7˜-ÕURO˜¦´f$ªž-Í6(œ}<„ éc øs]ŽŽ„*—¾ ìdŽ„)méª\¿êÎIg¾ØÞ~I#C/¼¼´EÁÈŽi8“©õådô·>euä ƒ'Ê×लR1ÉJE1ÐAát`t;ÇР%Ý<‡¥„ÍÆ`×Oyó)õiI€ñQaŸ4Ûù\áàaÃÔ¹HÃu¹*k€¦<„e S‡&õÏ B!ŽhüÞ`yj}mªf×\¿ Ç~æ­9‡û\՞Ǖg²1Žû5V7 !àöšm° c`ܬøÇìµÒ'P"?…´Ö,"§^•õލsÔ)6˜sæéÍR¼ ò|Sl”‹7 nPW Gòú÷½§O¯‡„l¡kSÞŒr½PÊ@æ¢pŽ-mÿ #Ÿ˜Àº¶Áä¦;ïÔæ$1££`“Õ>„—·ž)ßð³ñ#Ï Ô$¶œ‰ÊE‹À;÷º ¯«P:Ñ”8–IÊtpÞ3ª“>ê“þës4ò2OÏÕ­±zô†Õ§‰.÷ä¸;¿˜“'œ›žª}«Œ{ª±Ì 9ÔóÞÕ‡0 $íWV3Üì¬ —@kÝ4@¿r¼±½¬™›?øØæ´'Áé®CË3-g$˜ö‡×auÚi´Žp/êÛ æF›Ú2v‹ã¿¿,nB1̨ƃqÞa5͝@&Æû“él÷ \C²½UÍc ¯k×¢U ÖéQå™—-r wô ÞÏ<Ò=&=ÿ Ôê Òêˈt,i—;LîÜ á¸*ÚÃ1$êL•LÍ <É)ýÐà’ ;F™{ƒ™˜€&'}‚ãÄK`¡ÞT@I;®žZóè‚s’7®°›+§O­Åq©é»²9<Ô J ¼9O’HL»Ùïì¸rk¼Ž_ý‘TŸu[²ßÚŒ·ü÷B%¯E ŸÔX5êO´ Ç•€’I0 ÉJX` ñ¹õ%;µŸD‘«´€àwÒ™U ûئžÖö\×®×´8 ½‡ºÐÆÓ§?Àkmœ=;d5*@-ì0F Rªýš[Ü6âö̃ڸr*KA9· u*µæ£?U¸Âêí†8@¦X4 e-ò„0s{ HâUpU?¼mñRa°®a%Ð'tÉ×’\¾ÊÉ]t›h>·(Ë@R¼¡Ãt h}’O÷au<+nT…Ö…MӐ??Óe95 q>í/;&JSû °¯ÊéÞ øƒ*Ã2½Ài&:nôUl=¾¿5eˆ3”ñc|Ú2V”>„»&eE;«ÚäC p¢Û úy 9š[ŒÌx¼擼A&DåÒ¯ˆ¤ÀÌ;"˜ ÏQä¸åhÊ}Ûq«Û0WžÒ|»€ø®öCm5•\ÇÀ§Pe3£]0ÃàLDÉ‰1øªxjgwT‚÷¿LΨK‹›ùs—xˆÜ±µ kæ¸f‰‰ÜGk/LÛØ6d9ò¶ùA{ƒA3š/¬D¬khÓk‰`˜"㯒r¿±Óã jx‡°e}<Ñø\3y:'À•/h½Í€Ç4~g ?Û(¼]v‘ªlKÎâ~?O‚W%{Ì:“'©úNq¾›úo(X’¥¯ˆ nFê{Ç€ü?º'ë ø‹ì Þ09ŒÌç9Æ —ËC`j@ÓÄ(+a‹un¸#ÂꟋ{K`‘ÑÍÍ'à´»/Û,KW;Þ4²þð ï Nm|~fGÏ(…³Ã)«1ö­Õ ¥‡¨©ƒÃ™ü-s=à=U66Ï«Ýc蓦W¹íž®›nÔ%êÇìŒ<#Ü×84ån®Ð ÒåOC` ñânÑs‡¢ç 1õ%Îhì½Ã½® e:ݼUZo™`  ÅZŸŒÊ«ê1ÏÄo$q¹Þ€©ˆhÐÉä¯ñ[!…Ú˜àJ:x2$Íß&PåT£6ç— ‡Í*4Ýšçjÿ ‰É nófÐ ó(L5C•åÆ\rMÒ@ò }y-W}™üýVù—ú¢=Ù”c®‘< M ž ´Phr ¦©TD ‘ù.$´÷O‡‘V2Æò.=IUŒ=ž‡â¬i™aþÓåÙ?òUø'ØÖ•.~* šTŒ!•-×áºTâ®ä#õü'´ eýlYÅÓeÕKÂrT"CÚ@u!Óxƒ{š3€}1¿(r}%«nËamjÑ%ÑNEò v ˜à  σöK³,*º.àzù¨™Ó ÚçâU¦*¿ 9{%Ö¹ njûdaXöb) kÛÆ±ûÓ\°M7ˆÂ=û›ç¿Ã‚­V»Cg–8ÙêE- j)k$º`Ã-ùEýeBÆÇ]c¡°ñty&Òd0nõ'¡W+ƒ*|–øµFa\GQªEAÔp5\Ǽ·¼Ç8·õ -â§Ú[ ‡ uZeÖ 3}×d'+¹:ð+K†Û®s!Ï$úe€<Û”x)1»a­¡LC]¸µík…ÚàA»AYº{†ªS[¦5HÒ7ù --,ísòDØ€èk ÞÀîÜ ò@â( ËNˆë›4ô½•/¦o‡€Û7 ê•ÆêòðÜy'Án½µ á˜ݦ ndeo…[ì¶Ê,¥R³Ä=À±—–ß;£™´ñSâ*g§”ïaið‘Jå~™ÓÞ ß³Õ¢»8x埒²52>AÊb&-÷\7´éÄù€T˜,w;3{ï˜k…à¹ÄqÀ«œ{€\ ˆ¾[´¨јr &Úé„Ívˆ±8†¿]|¬ņ4I×pÞS1ÈÖz‰#Ìv‡G!YNògñ:màTz¢Ý1ô©^O=~ë|5Bã™ç•¼µõ•bÆ@úÕS¬ÈŒ#¬zünrŸ û” Z²•èðV"ÁHÚý©wÝ €7¼Ìu1hÑa3Éä û f$o¿É ™Ú›ÝçnpÒ3äÌ3†Í§,Äï]$‰/pê †«À¼¸e9­Æê_C]žƒ·ý·frÁN«, E=›Çq -‰öŒ:aÏ¿±í&£Í:-} 84‘ÿ eƒQÑeëSsuiA ³g㟥ú£?ÿ ʼn*”“÷aühe:ÊWa@ÒÞk±eØ] F Ô—r.åä˜ @ö¥ªZoÐýYL·¥S²G/‡ñ <~*ZÆ´è>JlòàÛÆ½ÿ 窘ìGN¢:I®KšJp/`íIÁÀõ#Ä-€ö­šµŒoF4|ÆQØÆ@Ì|£Ô…¢À{9˜è½Üó›€ôYÒÎYsið;ís¤€à²ˆ‚4qÉVŒI$ ‰"° æµ8cXGjœˏ¡Aâý•ËÜ¢ûï e·çLx']á"oÅÎê3¯Ç—¹”ó0nå‚âg{Œñ> S´˜îè°g238‚ãköÝfÚd´6Ò€;ò÷±¢™¼›º ¢Æ'¥Ðx'e¬ç ]bÈÆV¢ó‹kýBO ðÊâ$Ÿ!×T 3Mýמ žìٍàÌü‘8÷€àæØ8æ©6‰©L´«…oãpð„~Çk‰!ñ;‹”ÛžÍ àž±z Ÿôû øŸÝužÏ;ÿ #|u6™Þ¬ÚˆÐõA4¶â|ôl|Ê2ŽÇ¤ÝÅÇY.<#Aí.k§hóF‚”Y; M½Ö4hŸ4&›­¿tès´%FìL¥£Ãk‰ÇT¤haÁ¤ÚxfÉ`ÑìË›>i 3t‚:,–+^÷´–{Û–Nxi"x‘Ûg î¨>¥Õ܁ùZH,2Û“:8xÊ¢Çí9.É-Ìâã-=çjwµS˜dütžçwýGòú®®ûº_ˆýx$–¡ãøO EÚÛÏ÷R„×w+3£Á£öUMyR²¹âŒ°š›¸Ñãò9§Ó_Dl+Ùßc›úšGÅÌc†Ž!Ko=¶.‘Îÿ c²(2®V mª.ÿ ¹B›¹å ù„öŸSV>™ü¯$y:G¢Z×àøúdî¹û­·ýÇ´:•c LÍõi_‹ö+ÎæGÊè>OŠ•äž´§Þ{X}¨1ÚTc›»Qþ•êô°t¿OP?eæ~É{5]•ÙR£r5†nZ\ã@ &îJõ ¾àC°þV>fé¥/ü5ñÊIº_é5 ;e­h<@ Ä&æÃëE%;X,ÒãÆÞ`Oò¦kŸm#˜!ÀyÄ¢| óLšò¥Ä` ¶R=|ÈCâh5ò3DˆïF†ðÒ#ÅìÛœ?¸yhBãœí ZxßÎÄhºRK„`Þödvײ™ÀÈÑÒgŒuY w³%†ƒÓzõ ÖÏp‚dH®¦A´ù§»ÓÇMæ~)ˆð‡û:ù&Ä •vGD´À n ݇¼Ö8Fö óáà£~Ë¥x`oK|Ä?fxiØü%pìR>éò+Û±éÎ>núlFŤ'tq8LZÏvÃ?„¡ß±È⽆¯³íü@x|PöUäèØã¡ð‚ŒAìÏ"vÍwóŸÍ{ ý0.z È•Ö{,N¡£¡ŸKÕÙž>Ýœþ ÍÀ°<×EA!Å‚D™IúOÍ¡>ôG}Â` ÍßkÜL™Ž Þð™ {IøF²¹òQ3&!ÃÂÞz.d&Ï-sH¸,Ôõ˜ŽP€ 77ˆÝ¼ÊëÜw =cÕ Ú,ØÐ5ÎYÐ)ì´öœgŒ[¤ßv㙑8心>h]§µháYš£²ºÑ.{Ï7Sð•?´~×SÃKýJÛ˜ ™Íäiúu<µX¶1õ^kâçIÑ£sZ4h>j*ÔšD:4­¿_ ÷¸ Õxæÿ ¸?Mù _•­ÊÐ ä ÷ý ÑwL œ­ïnTkÛUÍN©ë:¦fV ¶ÜÔÜMªÅâA½–¿R×TXš-%iTÊT•‡Ù‚JôϐZxWÑè‰f‰òG º ×Õû2aZ7OU3[“×AT–ÞŒ…-‘¤”Ì ì&(ˆ¿­•ƒkï’:ðY¦W‘ Å)“†‘˜³Åtcø˜ñTÂwÚÇ4|üLÇªí–v- qˆèU qPE.†â‘˜µ Æ,ÐÅs]8¾„oúÑ i>ÜxxÈó)ƒ ´æÁâØ$À‰vžŸf$Ž |ãw;ÀÁIJ»b` {¦Ó¤Ú$©YÀ‘n@Óïž«9J¼êG m¤ ܯ¹ÌW4€ÐÒÅÛ‡#褕Ÿn-?í|с¥÷Ú¹¬'´ÞÜ9ÓK `hê£SÄSà?7—Wí_´…óB›»:=Ãïq`<8ñÓŒÑlú2d¬ê³£hÖ[l|$vÝro~'R®‰§°ñmY ͧäP |PUª¹·:3Œ[Û{Xÿ ºâ@‚W–Äé u‚ ¯´*=íή.pûÒdt @G‰¬ s¸ ëÉücr ÞæÑ¨Ê@>¤¢Ö±. Þ'¯°ÌME[YéïĵÂCå½ Ué©Áû'Ê9%eÔðNU”ë‘ÌsD3/®+UI˜9h.WC”빓$#:pz:YÓ ¿xž* ³$Í +$kñAŠ‹†¢ Uê>¸)_š¬÷©ßAÂÔb9ÇU ¯¾á•9¯ÏÏ÷O÷¼¼Fähal1‰3Ì[Ïr•´UCksNÐ] R‘¸¥H+§Šé†c©vÖÞ0iÓ76s†î!§=ß ¼~Ô'°Ãmäoäš³ªøi1úÉ)³yV8 CLÄØÁ‘WYïi€H6ÖÑiámø^ÈY´°Ñ7¥Û*—Ñ©L«Qƒï—Ùrÿ ›£Ð*š¸ˆL©ˆ$ˆ ÷¾D§9È®«qbqC)–ˆïv´çñsÑVT­Ø, <àïºÀO«Jý·õ àfPìð .wFšir´þ’2_Y *Æ€x\« ì€9š@ Ž|F⇥ˆkZ@hÖÄ0t¿-<“‹qµ¾*ZL¤Ú)&BJpÓF5=$„at*Zš$’ÑtdûÝRI1 2މ$€$I$#‰SÞ’Hë¬ï;Á$¡t$’`<(ñÇt)$‡Ð.Êf¢X’Kt=Éé$‚ˆªè¢oÝëòI%Rgcª÷ŠyI%¡‰ÿ !ñ)´õ $¤ Ô’IIGÿÙ# Test the windows specific win32reg module. # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey import os, sys, errno import unittest from test import support import threading from platform import machine, win32_edition # Do this first so test will be skipped if module doesn't exist support.import_module('winreg', required_on=['win']) # Now import everything from winreg import * try: REMOTE_NAME = sys.argv[sys.argv.index("--remote")+1] except (IndexError, ValueError): REMOTE_NAME = None # tuple of (major, minor) WIN_VER = sys.getwindowsversion()[:2] # Some tests should only run on 64-bit architectures where WOW64 will be. WIN64_MACHINE = True if machine() == "AMD64" else False # Starting with Windows 7 and Windows Server 2008 R2, WOW64 no longer uses # registry reflection and formerly reflected keys are shared instead. # Windows 7 and Windows Server 2008 R2 are version 6.1. Due to this, some # tests are only valid up until 6.1 HAS_REFLECTION = True if WIN_VER < (6, 1) else False # Use a per-process key to prevent concurrent test runs (buildbot!) from # stomping on each other. test_key_base = "Python Test Key [%d] - Delete Me" % (os.getpid(),) test_key_name = "SOFTWARE\\" + test_key_base # On OS'es that support reflection we should test with a reflected key test_reflect_key_name = "SOFTWARE\\Classes\\" + test_key_base test_data = [ ("Int Value", 45, REG_DWORD), ("Qword Value", 0x1122334455667788, REG_QWORD), ("String Val", "A string value", REG_SZ), ("StringExpand", "The path is %path%", REG_EXPAND_SZ), ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ), ("Multi-nul", ["", "", "", ""], REG_MULTI_SZ), ("Raw Data", b"binary\x00data", REG_BINARY), ("Big String", "x"*(2**14-1), REG_SZ), ("Big Binary", b"x"*(2**14), REG_BINARY), # Two and three kanjis, meaning: "Japan" and "Japanese". ("Japanese 日本", "日本語", REG_SZ), ] class BaseWinregTests(unittest.TestCase): def setUp(self): # Make sure that the test key is absent when the test # starts. self.delete_tree(HKEY_CURRENT_USER, test_key_name) def delete_tree(self, root, subkey): try: hkey = OpenKey(root, subkey, 0, KEY_ALL_ACCESS) except OSError: # subkey does not exist return while True: try: subsubkey = EnumKey(hkey, 0) except OSError: # no more subkeys break self.delete_tree(hkey, subsubkey) CloseKey(hkey) DeleteKey(root, subkey) def _write_test_data(self, root_key, subkeystr="sub_key", CreateKey=CreateKey): # Set the default value for this key. SetValue(root_key, test_key_name, REG_SZ, "Default value") key = CreateKey(root_key, test_key_name) self.assertTrue(key.handle != 0) # Create a sub-key sub_key = CreateKey(key, subkeystr) # Give the sub-key some named values for value_name, value_data, value_type in test_data: SetValueEx(sub_key, value_name, 0, value_type, value_data) # Check we wrote as many items as we thought. nkeys, nvalues, since_mod = QueryInfoKey(key) self.assertEqual(nkeys, 1, "Not the correct number of sub keys") self.assertEqual(nvalues, 1, "Not the correct number of values") nkeys, nvalues, since_mod = QueryInfoKey(sub_key) self.assertEqual(nkeys, 0, "Not the correct number of sub keys") self.assertEqual(nvalues, len(test_data), "Not the correct number of values") # Close this key this way... # (but before we do, copy the key as an integer - this allows # us to test that the key really gets closed). int_sub_key = int(sub_key) CloseKey(sub_key) try: QueryInfoKey(int_sub_key) self.fail("It appears the CloseKey() function does " "not close the actual key!") except OSError: pass # ... and close that key that way :-) int_key = int(key) key.Close() try: QueryInfoKey(int_key) self.fail("It appears the key.Close() function " "does not close the actual key!") except OSError: pass def _read_test_data(self, root_key, subkeystr="sub_key", OpenKey=OpenKey): # Check we can get default value for this key. val = QueryValue(root_key, test_key_name) self.assertEqual(val, "Default value", "Registry didn't give back the correct value") key = OpenKey(root_key, test_key_name) # Read the sub-keys with OpenKey(key, subkeystr) as sub_key: # Check I can enumerate over the values. index = 0 while 1: try: data = EnumValue(sub_key, index) except OSError: break self.assertEqual(data in test_data, True, "Didn't read back the correct test data") index = index + 1 self.assertEqual(index, len(test_data), "Didn't read the correct number of items") # Check I can directly access each item for value_name, value_data, value_type in test_data: read_val, read_typ = QueryValueEx(sub_key, value_name) self.assertEqual(read_val, value_data, "Could not directly read the value") self.assertEqual(read_typ, value_type, "Could not directly read the value") sub_key.Close() # Enumerate our main key. read_val = EnumKey(key, 0) self.assertEqual(read_val, subkeystr, "Read subkey value wrong") try: EnumKey(key, 1) self.fail("Was able to get a second key when I only have one!") except OSError: pass key.Close() def _delete_test_data(self, root_key, subkeystr="sub_key"): key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS) sub_key = OpenKey(key, subkeystr, 0, KEY_ALL_ACCESS) # It is not necessary to delete the values before deleting # the key (although subkeys must not exist). We delete them # manually just to prove we can :-) for value_name, value_data, value_type in test_data: DeleteValue(sub_key, value_name) nkeys, nvalues, since_mod = QueryInfoKey(sub_key) self.assertEqual(nkeys, 0, "subkey not empty before delete") self.assertEqual(nvalues, 0, "subkey not empty before delete") sub_key.Close() DeleteKey(key, subkeystr) try: # Shouldn't be able to delete it twice! DeleteKey(key, subkeystr) self.fail("Deleting the key twice succeeded") except OSError: pass key.Close() DeleteKey(root_key, test_key_name) # Opening should now fail! try: key = OpenKey(root_key, test_key_name) self.fail("Could open the non-existent key") except OSError: # Use this error name this time pass def _test_all(self, root_key, subkeystr="sub_key"): self._write_test_data(root_key, subkeystr) self._read_test_data(root_key, subkeystr) self._delete_test_data(root_key, subkeystr) def _test_named_args(self, key, sub_key): with CreateKeyEx(key=key, sub_key=sub_key, reserved=0, access=KEY_ALL_ACCESS) as ckey: self.assertTrue(ckey.handle != 0) with OpenKeyEx(key=key, sub_key=sub_key, reserved=0, access=KEY_ALL_ACCESS) as okey: self.assertTrue(okey.handle != 0) class LocalWinregTests(BaseWinregTests): def test_registry_works(self): self._test_all(HKEY_CURRENT_USER) self._test_all(HKEY_CURRENT_USER, "日本-subkey") def test_registry_works_extended_functions(self): # Substitute the regular CreateKey and OpenKey calls with their # extended counterparts. # Note: DeleteKeyEx is not used here because it is platform dependent cke = lambda key, sub_key: CreateKeyEx(key, sub_key, 0, KEY_ALL_ACCESS) self._write_test_data(HKEY_CURRENT_USER, CreateKey=cke) oke = lambda key, sub_key: OpenKeyEx(key, sub_key, 0, KEY_READ) self._read_test_data(HKEY_CURRENT_USER, OpenKey=oke) self._delete_test_data(HKEY_CURRENT_USER) def test_named_arguments(self): self._test_named_args(HKEY_CURRENT_USER, test_key_name) # Use the regular DeleteKey to clean up # DeleteKeyEx takes named args and is tested separately DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_connect_registry_to_local_machine_works(self): # perform minimal ConnectRegistry test which just invokes it h = ConnectRegistry(None, HKEY_LOCAL_MACHINE) self.assertNotEqual(h.handle, 0) h.Close() self.assertEqual(h.handle, 0) def test_nonexistent_remote_registry(self): connect = lambda: ConnectRegistry("abcdefghijkl", HKEY_CURRENT_USER) self.assertRaises(OSError, connect) def testExpandEnvironmentStrings(self): r = ExpandEnvironmentStrings("%windir%\\test") self.assertEqual(type(r), str) self.assertEqual(r, os.environ["windir"] + "\\test") def test_context_manager(self): # ensure that the handle is closed if an exception occurs try: with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as h: self.assertNotEqual(h.handle, 0) raise OSError except OSError: self.assertEqual(h.handle, 0) def test_changing_value(self): # Issue2810: A race condition in 2.6 and 3.1 may cause # EnumValue or QueryValue to raise "WindowsError: More data is # available" done = False class VeryActiveThread(threading.Thread): def run(self): with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: use_short = True long_string = 'x'*2000 while not done: s = 'x' if use_short else long_string use_short = not use_short SetValue(key, 'changing_value', REG_SZ, s) thread = VeryActiveThread() thread.start() try: with CreateKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value') as key: for _ in range(1000): num_subkeys, num_values, t = QueryInfoKey(key) for i in range(num_values): name = EnumValue(key, i) QueryValue(key, name[0]) finally: done = True thread.join() DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value') DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_long_key(self): # Issue2810, in 2.6 and 3.1 when the key name was exactly 256 # characters, EnumKey raised "WindowsError: More data is # available" name = 'x'*256 try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: SetValue(key, name, REG_SZ, 'x') num_subkeys, num_values, t = QueryInfoKey(key) EnumKey(key, 0) finally: DeleteKey(HKEY_CURRENT_USER, '\\'.join((test_key_name, name))) DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_dynamic_key(self): # Issue2810, when the value is dynamically generated, these # raise "WindowsError: More data is available" in 2.6 and 3.1 try: EnumValue(HKEY_PERFORMANCE_DATA, 0) except OSError as e: if e.errno in (errno.EPERM, errno.EACCES): self.skipTest("access denied to registry key " "(are you running in a non-interactive session?)") raise QueryValueEx(HKEY_PERFORMANCE_DATA, "") # Reflection requires XP x64/Vista at a minimum. XP doesn't have this stuff # or DeleteKeyEx so make sure their use raises NotImplementedError @unittest.skipUnless(WIN_VER < (5, 2), "Requires Windows XP") def test_reflection_unsupported(self): try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: self.assertNotEqual(ck.handle, 0) key = OpenKey(HKEY_CURRENT_USER, test_key_name) self.assertNotEqual(key.handle, 0) with self.assertRaises(NotImplementedError): DisableReflectionKey(key) with self.assertRaises(NotImplementedError): EnableReflectionKey(key) with self.assertRaises(NotImplementedError): QueryReflectionKey(key) with self.assertRaises(NotImplementedError): DeleteKeyEx(HKEY_CURRENT_USER, test_key_name) finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_setvalueex_value_range(self): # Test for Issue #14420, accept proper ranges for SetValueEx. # Py2Reg, which gets called by SetValueEx, was using PyLong_AsLong, # thus raising OverflowError. The implementation now uses # PyLong_AsUnsignedLong to match DWORD's size. try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: self.assertNotEqual(ck.handle, 0) SetValueEx(ck, "test_name", None, REG_DWORD, 0x80000000) finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_queryvalueex_return_value(self): # Test for Issue #16759, return unsigned int from QueryValueEx. # Reg2Py, which gets called by QueryValueEx, was returning a value # generated by PyLong_FromLong. The implementation now uses # PyLong_FromUnsignedLong to match DWORD's size. try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: self.assertNotEqual(ck.handle, 0) test_val = 0x80000000 SetValueEx(ck, "test_name", None, REG_DWORD, test_val) ret_val, ret_type = QueryValueEx(ck, "test_name") self.assertEqual(ret_type, REG_DWORD) self.assertEqual(ret_val, test_val) finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_setvalueex_crash_with_none_arg(self): # Test for Issue #21151, segfault when None is passed to SetValueEx try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: self.assertNotEqual(ck.handle, 0) test_val = None SetValueEx(ck, "test_name", 0, REG_BINARY, test_val) ret_val, ret_type = QueryValueEx(ck, "test_name") self.assertEqual(ret_type, REG_BINARY) self.assertEqual(ret_val, test_val) finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) def test_read_string_containing_null(self): # Test for issue 25778: REG_SZ should not contain null characters try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: self.assertNotEqual(ck.handle, 0) test_val = "A string\x00 with a null" SetValueEx(ck, "test_name", 0, REG_SZ, test_val) ret_val, ret_type = QueryValueEx(ck, "test_name") self.assertEqual(ret_type, REG_SZ) self.assertEqual(ret_val, "A string") finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests") class RemoteWinregTests(BaseWinregTests): def test_remote_registry_works(self): remote_key = ConnectRegistry(REMOTE_NAME, HKEY_CURRENT_USER) self._test_all(remote_key) @unittest.skipUnless(WIN64_MACHINE, "x64 specific registry tests") class Win64WinregTests(BaseWinregTests): def test_named_arguments(self): self._test_named_args(HKEY_CURRENT_USER, test_key_name) # Clean up and also exercise the named arguments DeleteKeyEx(key=HKEY_CURRENT_USER, sub_key=test_key_name, access=KEY_ALL_ACCESS, reserved=0) @unittest.skipIf(win32_edition() in ('WindowsCoreHeadless', 'IoTEdgeOS'), "APIs not available on WindowsCoreHeadless") def test_reflection_functions(self): # Test that we can call the query, enable, and disable functions # on a key which isn't on the reflection list with no consequences. with OpenKey(HKEY_LOCAL_MACHINE, "Software") as key: # HKLM\Software is redirected but not reflected in all OSes self.assertTrue(QueryReflectionKey(key)) self.assertIsNone(EnableReflectionKey(key)) self.assertIsNone(DisableReflectionKey(key)) self.assertTrue(QueryReflectionKey(key)) @unittest.skipUnless(HAS_REFLECTION, "OS doesn't support reflection") def test_reflection(self): # Test that we can create, open, and delete keys in the 32-bit # area. Because we are doing this in a key which gets reflected, # test the differences of 32 and 64-bit keys before and after the # reflection occurs (ie. when the created key is closed). try: with CreateKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY) as created_key: self.assertNotEqual(created_key.handle, 0) # The key should now be available in the 32-bit area with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY) as key: self.assertNotEqual(key.handle, 0) # Write a value to what currently is only in the 32-bit area SetValueEx(created_key, "", 0, REG_SZ, "32KEY") # The key is not reflected until created_key is closed. # The 64-bit version of the key should not be available yet. open_fail = lambda: OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_READ | KEY_WOW64_64KEY) self.assertRaises(OSError, open_fail) # Now explicitly open the 64-bit version of the key with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY) as key: self.assertNotEqual(key.handle, 0) # Make sure the original value we set is there self.assertEqual("32KEY", QueryValue(key, "")) # Set a new value, which will get reflected to 32-bit SetValueEx(key, "", 0, REG_SZ, "64KEY") # Reflection uses a "last-writer wins policy, so the value we set # on the 64-bit key should be the same on 32-bit with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_READ | KEY_WOW64_32KEY) as key: self.assertEqual("64KEY", QueryValue(key, "")) finally: DeleteKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, KEY_WOW64_32KEY, 0) @unittest.skipUnless(HAS_REFLECTION, "OS doesn't support reflection") def test_disable_reflection(self): # Make use of a key which gets redirected and reflected try: with CreateKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY) as created_key: # QueryReflectionKey returns whether or not the key is disabled disabled = QueryReflectionKey(created_key) self.assertEqual(type(disabled), bool) # HKCU\Software\Classes is reflected by default self.assertFalse(disabled) DisableReflectionKey(created_key) self.assertTrue(QueryReflectionKey(created_key)) # The key is now closed and would normally be reflected to the # 64-bit area, but let's make sure that didn't happen. open_fail = lambda: OpenKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_READ | KEY_WOW64_64KEY) self.assertRaises(OSError, open_fail) # Make sure the 32-bit key is actually there with OpenKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0, KEY_READ | KEY_WOW64_32KEY) as key: self.assertNotEqual(key.handle, 0) finally: DeleteKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, KEY_WOW64_32KEY, 0) def test_exception_numbers(self): with self.assertRaises(FileNotFoundError) as ctx: QueryValue(HKEY_CLASSES_ROOT, 'some_value_that_does_not_exist') if __name__ == "__main__": if not REMOTE_NAME: print("Remote registry calls can be tested using", "'test_winreg.py --remote \\\\machine_name'") unittest.main()