tag:blogger.com,1999:blog-16503181423820984952024-03-04T20:30:03.088-08:00Sam's CodeWindows Systems Programmingsamhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.comBlogger74125tag:blogger.com,1999:blog-1650318142382098495.post-51273897842787692532022-04-29T17:36:00.002-07:002023-08-01T13:59:56.243-07:00How to Enable Application Verifier in Windbg<p><br />This is how you enable Application Verifier (appverif) if you are already in the debugger:<br /><br /></p><pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;"><blockquote>0:000> !gflag +vrf
Current NtGlobalFlag contents: 0x00000100
vrf - Enable application verifier
</blockquote></span></pre>You can then control verifier with the !avrf command.<p>This will display the current settings: </p><p><span style="background-color: white; color: #1e1e1e; font-family: Consolas; white-space: pre;"></span></p><blockquote>0:000> !avrf
Verifier package version >= 3.00
Application verifier settings (81000000):
- no heap checking enabled!
- SRWLock</blockquote><p></p><p>Other notes:</p><p>If you see something like this, then verifier is not setup on the exe.</p><span style="background-color: white; color: #1e1e1e; font-family: Consolas;"></span><blockquote><span style="background-color: white; color: #1e1e1e; font-family: Consolas;">No type information found for `verifier!_DPH_HEAP_ROOT'.</span><div><span style="background-color: white; color: #1e1e1e; font-family: Consolas;">Please fix the symbols for `verifier.dll'.</span></div></blockquote><div><span style="background-color: white; color: #1e1e1e; font-family: Consolas;"></span></div>samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-92005938648840134522022-04-11T17:02:00.004-07:002022-04-11T17:02:44.753-07:00Spin Until the Debugger Is Attached<p>Here is a handy trick to make some code wait for a debugger to attach. </p><p>Let's say you have some user mode code you need to debug and it has some kind of tricky activation flow that makes it hard to get a debugger on the process before the code executes. </p><p>In my case, I was helping someone on my team debug some test failures. Some weirdness was happing when the test activated an out-of-proc COM object. The COM server was getting loaded into a COM surrogate dllhost.exe. We added some more WPP tracing to see if we could narrow down the issue, and the was happening when the COM object was getting activated.</p><p>We tried to use named pipe debugging <a href="https://samscode.blogspot.com/2010/08/howto-debug-windows-service-using.html">like I outlined before</a> but it wasn't really applicable because it was using the surrogate instead of the svchost. </p><p>You can also set up windbg to automatically attach to the children of the process that you are currently debugging, but that didn't help either. The COM runtime was the one creating the process. I can't remember exactly, but I think it was the RPC endpoint mapper doing it.</p><p>Then the thought I had was to just make the COM server sleep for long enough for me to attach a user-mode debugger for say 30 sec. Our traces were showing the server's PID, or you can also use tlist.exe to find the PID. Instead of waiting for a long timeout, I added some code that spins until a debugger is attached.</p><p>Here is the code that spins until a debugger attaches.</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p style="text-align: left;"><span style="font-family: courier;"><span style="background-color: white; color: #242424; font-size: 11pt; font-style: inherit; font-weight: inherit;">while (!IsDebuggerPresent()) {</span></span></p><p style="text-align: left;"><span style="background-color: white; color: #242424; font-size: 11pt; font-style: inherit; font-weight: inherit;"><span style="font-family: courier;"> Sleep(1000);</span></span></p><p style="-webkit-font-smoothing: antialiased; background-color: white; box-sizing: border-box; color: #242424; font-size: 14px; margin: 0px; text-align: left;"><span style="-webkit-font-smoothing: antialiased; box-sizing: border-box; font-size: 11pt; font-style: inherit; font-weight: inherit;"><span style="font-family: courier;">} </span></span></p><p style="-webkit-font-smoothing: antialiased; background-color: white; box-sizing: border-box; color: #242424; font-size: 14px; margin: 0px; text-align: left;"><span style="-webkit-font-smoothing: antialiased; box-sizing: border-box; font-size: 11pt; font-style: inherit; font-weight: inherit;"><span style="font-family: courier;">__debugbreak();</span></span></p></blockquote><p> </p>samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-69299809407916668872021-05-19T11:19:00.002-07:002021-05-19T11:19:33.602-07:00windbg: changing stepping by line instead of instruction<p> In recently nightly builds of windbgx, I've noticed it has changed the initial default step behavior, or source mode. Typically while source code debugging, when you press F10, or 'p', it steps by one line of code, which is called source mode. Windbgx has recently been defaulting to stepping by instruction, which is called assembly mode. A line of code is often several instructions, so you end up pressing F10 a lot to step through a number of lines of code which is generally not what you want if you have source while debugging.</p><p>The source stepping options are controlled by the 'l' command. <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/l---l---set-source-options-">Here is the documentation</a>, but basically you wan the 't' mode to step by lines of code instead of instructions. Without the 't', the debugger is in <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-in-assembly-mode">assembly mode</a> instead of <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-in-source-mode">source mode</a>.</p><p>The command to go to source mode is the following:</p><blockquote style="border: none; margin: 0 0 0 40px; padding: 0px;"><p style="text-align: left;">> l+t</p></blockquote><p><br /></p>samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-16035504059252653192020-11-16T12:38:00.003-08:002020-12-16T12:46:58.365-08:00COM Access Violation (AV) Crashes Relating to Unloaded DLLs<p>My team uses a broadly used WinRT API. Basically, all apps that have a device-related scenario use it. This means buggy apps that crash will sometimes have our component featured in their Watson dumps. Based on certain metrics, Watson will turn buckets turn into code bugs, so we have to triage them. Aside: in case you were wondering, bugs from WER (Windows Error Reporting) service and dumps, do generate bugs and get fixed, so WER is useful.</p><p>A number of AV crash bugs we see are related to our device watcher calling back into the app's handlers for the device events, which almost always means a lifetime management bug in the app. </p><p>You can check the memory allocations to see if they are busy or free. This applies more to the component that owns the object's memory. I think I covered that before. That will let you know if the object has already been released. A lot of times you can still see the object's state after it has been freed, but the important part is that it has been released/freed already, so the object is not being ref counted correctly. AppVerif has a handy COM set of checks which might help if you think you may have this problem in your code. With <i>smart pointers</i>, it can be a little harder to see what is happening with the object's references. If the object model is not too complicated, you can just find the bug with code inspection.</p><p>A super common reason for AVs like this is the DLL is unloaded. COM aggressively unloads DLLs not being used by calling DllCanUnloadNow. If the implementation has a bug, the DLL will get unloaded while objects and other COM operations are in flight. Eventually, when COM tries to CoUnitialize an object that belongs to that DLL, it will AV. This also applies to other COM things like when COM tries to marshal between apartments, etc.</p><p> We see crashes like this fairly often:</p><p></p><pre style="border: 1px solid rgb(234, 236, 240); line-height: 1.3em; padding: 1em; text-align: left;"><pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">0:049> .excr
rax=00007ff8f305cf70 rbx=0000026dfc5cc900 rcx=0000026dfc5cc900
rdx=0000000000012f06 rsi=0000026dfa091b00 rdi=0000026dfa091ae0
rip=00007ff990c9094d rsp=000000b92deff490 rbp=00000000800401fd
r8=00007ff970a0b370 r9=000000b92deff5d0 r10=dee01e7974d59970
r11=000000b92deff5e0 r12=0000000000012f06 r13=00007ff970a0b370
r14=000000b92deff5d0 r15=00007ff8f305cf70
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
combase!CGIPTable::GetRequestedInterface+0x22 [inlined in combase!CGIPTable::GetInterfaceFromGlobal+0x1ed]:
00007ff9`90c9094d 488b00 mov rax,qword ptr [rax] ds:00007ff8`f305cf70=????????????????
0:049> k
*** Stack trace for last set context - .thread/.cxr resets it
# Child-SP RetAddr Call Site
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">00</span><span style="background-color: white; color: #1e1e1e;"> (Inline Function) --------`-------- combase!CGIPTable::GetRequestedInterface+0x22 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\com\combase\dcomrem\giptbl.cxx</span><span style="background-color: white; color: #1e1e1e;"> @ 1615]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">01</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff490 00007ff9`7097515b combase!CGIPTable::GetInterfaceFromGlobal+0x1ed [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\com\combase\dcomrem\giptbl.cxx</span><span style="background-color: white; color: #1e1e1e;"> @ 1660]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">02</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff560 00007ff9`70977823 Windows_Devices_Enumeration!Gip<Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *> >::Localize+0x6b [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\private\base\inc\devices\Git.h</span><span style="background-color: white; color: #1e1e1e;"> @ 167]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">03</span><span style="background-color: white; color: #1e1e1e;"> (Inline Function) --------`-------- Windows_Devices_Enumeration!GitDelegate2<Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *>,Windows::Devices::Enumeration::IDeviceWatcher *,Windows::Devices::Enumeration::IDeviceInformation *>::GetHandler+0x11 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecoreuap\base\devices\rtenum\dllsrv\GitDelegate.h</span><span style="background-color: white; color: #1e1e1e;"> @ 254]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">04</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff5a0 00007ff9`70976d95 Windows_Devices_Enumeration!GitDelegate2<Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *>,Windows::Devices::Enumeration::IDeviceWatcher *,Windows::Devices::Enumeration::IDeviceInformation *>::Invoke+0x23 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecoreuap\base\devices\rtenum\dllsrv\GitDelegate.h</span><span style="background-color: white; color: #1e1e1e;"> @ 303]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">05</span><span style="background-color: white; color: #1e1e1e;"> (Inline Function) --------`-------- Windows_Devices_Enumeration!Microsoft::WRL::EventSource<Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *>,Microsoft::WRL::InvokeModeOptions<-2> >::InvokeAll::__l2::<lambda_00d1300cb6cb75d6b2b5344e37267964>::operator()+0x36 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\external\sdk\inc\wrl\event.h</span><span style="background-color: white; color: #1e1e1e;"> @ 964]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">06</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff5d0 00007ff9`70976cf4 Windows_Devices_Enumeration!Microsoft::WRL::InvokeTraits<-2>::InvokeDelegates<<lambda_00d1300cb6cb75d6b2b5344e37267964>,Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *> >+0x79 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\internal\sdk\inc\wrl\internalevent.h</span><span style="background-color: white; color: #1e1e1e;"> @ 121]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">07</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff630 00007ff9`70981d3d Windows_Devices_Enumeration!Microsoft::WRL::EventSource<Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *>,Microsoft::WRL::InvokeModeOptions<-2> >::DoInvoke<<lambda_00d1300cb6cb75d6b2b5344e37267964> >+0x78 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\external\sdk\inc\wrl\event.h</span><span style="background-color: white; color: #1e1e1e;"> @ 954]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">08</span><span style="background-color: white; color: #1e1e1e;"> (Inline Function) --------`-------- Windows_Devices_Enumeration!Microsoft::WRL::EventSource<Windows::Foundation::ITypedEventHandler<Windows::Devices::Enumeration::DeviceWatcher *,Windows::Devices::Enumeration::DeviceInformation *>,Microsoft::WRL::InvokeModeOptions<-2> >::InvokeAll+0x19 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\external\sdk\inc\wrl\event.h</span><span style="background-color: white; color: #1e1e1e;"> @ 964]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">09</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff670 00007ff9`8ee2d946 Windows_Devices_Enumeration!Watcher<Windows::Devices::Enumeration::DeviceWatcher,Windows::Devices::Enumeration::IDeviceWatcher,Windows::Devices::Enumeration::IDeviceWatcher2,Windows::Devices::Enumeration::DeviceInformation,Windows::Devices::Enumeration::IDeviceInformation,Windows::Devices::Enumeration::IDeviceInformation2,DeviceInformationServer,Windows::Devices::Enumeration::DeviceInformationUpdate,Windows::Devices::Enumeration::IDeviceInformationUpdate,DeviceInformationUpdateServer,&RuntimeClass_Windows_Devices_Enumeration_DeviceWatcher>::Impl::DevQueryCallback+0x3ad [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecoreuap\base\devices\rtenum\dllsrv\Watcher.h</span><span style="background-color: white; color: #1e1e1e;"> @ 889]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">0a</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff710 00007ff9`91b9b0ea cfgmgr32!TQuery::ServiceActionQueue+0xe2 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\base\pnp\devquery\lib\query.cpp</span><span style="background-color: white; color: #1e1e1e;"> @ 245]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">0b</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff7a0 00007ff9`91b3ec06 ntdll!TppWorkpExecuteCallback+0x13a [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">minkernel\threadpool\ntdll\work.c</span><span style="background-color: white; color: #1e1e1e;"> @ 671]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">0c</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deff7f0 00007ff9`8ff94ede ntdll!TppWorkerThread+0x686 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">minkernel\threadpool\ntdll\worker.c</span><span style="background-color: white; color: #1e1e1e;"> @ 1109]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">0d</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deffae0 00007ff9`91b87c6b kernel32!BaseThreadInitThunk+0x1e [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">clientcore\base\win32\client\thread.c</span><span style="background-color: white; color: #1e1e1e;"> @ 70]
</span><span style="background-color: white; color: blue; text-decoration-line: underline;">0e</span><span style="background-color: white; color: #1e1e1e;"> 000000b9`2deffb10 00000000`00000000 ntdll!RtlUserThreadStart+0x2b [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">minkernel\ntdll\rtlstrt.c</span><span style="background-color: white; color: #1e1e1e;"> @ 1152]
0:049> .frame 0n0;dv /t /v
00 (Inline Function) --------`-------- combase!CGIPTable::GetRequestedInterface+0x22 [</span><span style="background-color: white; color: blue; text-decoration-line: underline;">onecore\com\combase\dcomrem\giptbl.cxx</span><span style="background-color: white; color: #1e1e1e;"> @ 1615]
@rbx struct IUnknown * </span><span style="background-color: white; color: blue; text-decoration-line: underline;">pUnk</span><span style="background-color: white; color: #1e1e1e;"> = 0x0000026d`fc5cc900
@r15 void * pVtableAddress = 0x00007ff8`f305cf70
<unavailable> HRESULT hr = <value unavailable>
0:049> dps 0x0000026d`fc5cc900
0000026d`fc5cc900 00007ff8`f305cf70 </span><span style="background-color: #fcff01; color: #1e1e1e;"><Unloaded_xxxxxxxxx.dll></span><span style="background-color: white; color: #1e1e1e;">+0xc2cf70
0000026d`fc5cc908 00000001`00000000
0000026d`fc5cc910 0000026d`fbdc9af0
0000026d`fc5cc918 00080000`00000000
0000026d`fc5cc920 00000000`00000008
0000026d`fc5cc928 00000008`4d454d4c
0000026d`fc5cc930 0000026d`fc4d3bf8</span></pre></pre><pre style="border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;"><span style="background-color: #f8f9fa;">You can see that the </span><span style="background-color: #fcff01;">handler's dll</span><span style="background-color: #f8f9fa;"> is already unloaded.</span></pre><pre style="background-color: #f8f9fa; border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;">// or another example ///</pre><pre style="background-color: #f8f9fa; border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;">:000> k
combase!CStdMarshal::DisconnectSrvIPIDs::__l29::<lambda_2a3a7b5175b0a5e47c77e1d8eff078e5>::operator()+0x7
combase!ObjectMethodExceptionHandlingAction<<lambda_2a3a7b5175b0a5e47c77e1d8eff078e5> >+0x24
combase!CStdMarshal::DisconnectSrvIPIDs+0x30d
combase!CStdMarshal::DisconnectWorker_ReleasesLock+0x2d7
combase!CStdMarshal::DisconnectSwitch_ReleasesLock+0x1c
combase!CStdMarshal::DisconnectAndReleaseWorker_ReleasesLock+0x32
combase!COIDTable::ThreadCleanup+0x117
combase!FinishShutdown::__l2::<lambda_3d4acc620ec77839d81caec938b15158>::operator()+0x5
combase!ObjectMethodExceptionHandlingAction<<lambda_3d4acc620ec77839d81caec938b15158> >+0x9
combase!FinishShutdown+0x78
combase!ApartmentUninitialize+0xc9
combase!wCoUninitialize+0x17d
combase!CoUninitialize+0xea
wuaueng!UHRunRemoteHandlerServer+0x25e
...</pre><div><pre style="border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;"><span style="background-color: #f8f9fa;">0:000> .exr -1
ExceptionAddress: 00007ffe8571a510 (combase!CStdMarshal::DisconnectSrvIPIDs::__l29::<lambda_2a3a7b5175b0a5e47c77e1d8eff078e5>::operator()+0x0000000000000007)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Attempt to read from address 00007ffe59d74ee8
0:000> ln 00007ffe59d74ee8
(00007ffe`59d74ee8) </span><span style="background-color: #fcff01;"><Unloaded_xxxxxxxxxxx.dll>+0x1b4ee8</span><span style="background-color: #f8f9fa;">
</span></pre></div>samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-86781444145948129502019-11-03T20:08:00.002-08:002019-11-04T09:54:52.126-08:00Howto: Enable Application Verifier Within WinDbg<h3 style="background: none rgb(255, 255, 255); border-bottom: 0px; font-family: "Segoe UI"; font-size: 1.2em; line-height: 1.6; margin: 0.3em 0px 0px; overflow: hidden; padding-bottom: 0px; padding-top: 0.5em;">
<span class="mw-headline" id=".21gflag_debugger_extention">!gflag debugger extention</span></h3>
<div style="background-color: white; color: #222222; font-family: "Segoe UI"; font-size: 14px; line-height: inherit; margin-bottom: 0.5em; margin-top: 0.5em;">
A quick way to enable AppVerifier settings from the kernel debugger is to use !gflag debugger extension. This extension also enables Heaps, Handles and Locks checks only. Any process that is launched after the settings are enabled will run with these AppVerifier settings.</div>
<div style="background-color: white; color: #222222; font-family: "Segoe UI"; font-size: 14px; line-height: inherit; margin-bottom: 0.5em; margin-top: 0.5em;">
To enable lite pageheap, Handles and Locks checks on all apps that start from here on:</div>
<pre style="background-color: #f8f9fa; border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;"> kd>!gflag +vrf
</pre>
<div style="background-color: white; color: #222222; font-family: "Segoe UI"; font-size: 14px; line-height: inherit; margin-bottom: 0.5em; margin-top: 0.5em;">
To enable full pageheap</div>
<pre style="background-color: #f8f9fa; border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;"> kd>!gflag +hpa
</pre>
<div style="background-color: white; color: #222222; font-family: "Segoe UI"; font-size: 14px; line-height: inherit; margin-bottom: 0.5em; margin-top: 0.5em;">
To disable settings:</div>
<pre style="background-color: #f8f9fa; border: 1px solid rgb(234, 236, 240); font-family: monospace, monospace; font-size: 14px; line-height: 1.3em; padding: 1em; white-space: pre-wrap;"> kd>!gflag -vrf
kd>!gflag -hpa</pre>
<div style="background-color: white; color: #222222; font-family: "segoe ui"; font-size: 14px; line-height: inherit; margin-bottom: 0.5em; margin-top: 0.5em;">
<h3 style="background-attachment: initial; background-clip: initial; background-image: none; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-bottom: 0px; color: black; font-size: 1.2em; line-height: 1.6; margin: 0.3em 0px 0px; overflow: hidden; padding-bottom: 0px; padding-top: 0.5em;">
<span class="mw-headline" id=".21gflag_debugger_extention">!avrf debugger extention</span></h3>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
The <span style="box-sizing: inherit; font-weight: bolder;">!avrf</span> extension controls the settings of <a data-linktype="external" href="https://docs.microsoft.com/windows-hardware/drivers/devtest/application-verifier" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline: 0px; overflow-wrap: break-word;">Application Verifier</a> and displays a variety of output produced by Application Verifier.</div>
<pre class="has-inner-focus" style="-webkit-font-smoothing: auto; background-color: var(--body-background-medium); border: 1px solid var(--border); box-sizing: inherit; color: #171717; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace !important; font-size: 0.875rem; hyphens: none; line-height: 19px; overflow-wrap: normal; overflow: auto; padding: 1rem; tab-size: 4; word-break: normal;" tabindex="0"><code class="lang-dbgcmd" data-author-content=" !avrf
!avrf -vs { Length | -a Address }
!avrf -hp { Length | -a Address }
!avrf -cs { Length | -a Address }
!avrf -dlls [ Length ]
!avrf -trm
!avrf -ex [ Length ]
!avrf -threads [ ThreadID ]
!avrf -tp [ ThreadID ]
!avrf -srw [ Address | Address Length ] [ -stats ]
!avrf -leak [ -m ModuleName] [ -r ResourceType] [ -a Address ] [ -t ]
!avrf -trace TraceIndex
!avrf -cnt
!avrf -brk [BreakEventType]
!avrf -flt [EventType Probability]
!avrf -flt break EventType
!avrf -flt stacks Length
!avrf -trg [ Start End | dll Module | all ]
!avrf -settings
!avrf -skp [ Start End | dll Module | all | Time ]
" style="border: 0px; box-sizing: inherit; direction: ltr; display: block; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 1em; line-height: 19px; padding: 0px; position: relative;"> !avrf
!avrf -vs { Length | -a Address }
!avrf -hp { Length | -a Address }
!avrf -cs { Length | -a Address }
!avrf -dlls [ Length ]
!avrf -trm
!avrf -ex [ Length ]
!avrf -threads [ ThreadID ]
!avrf -tp [ ThreadID ]
!avrf -srw [ Address | Address Length ] [ -stats ]
!avrf -leak [ -m ModuleName] [ -r ResourceType] [ -a Address ] [ -t ]
!avrf -trace TraceIndex
!avrf -cnt
!avrf -brk [BreakEventType]
!avrf -flt [EventType Probability]
!avrf -flt break EventType
!avrf -flt stacks Length
!avrf -trg [ Start End | dll Module | all ]
!avrf -settings
!avrf -skp [ Start End | dll Module | all | Time ]
</code></pre>
<h2 id="parameters" style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 1.75rem; line-height: 1.3; margin: 32px 0px 12px; padding: 0px;">
<span id="ddk__avrf_dbg" style="box-sizing: inherit;"></span><span id="DDK__AVRF_DBG" style="box-sizing: inherit;"></span>Parameters<a aria-labelledby="parameters" class="docon docon-link heading-anchor" href="https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-avrf#parameters" style="-webkit-font-smoothing: antialiased; background-color: transparent; border: 0px; box-sizing: inherit; clip-path: inset(50%); clip: rect(1px, 1px, 1px, 1px); cursor: pointer; direction: ltr; display: inline-block; font-family: docons; font-size: 0.8em; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; height: 1px; line-height: 16px; margin: -1px; opacity: 0; outline: 0px; overflow-wrap: normal; overflow: hidden; padding: 0px; position: absolute; speak: none; text-align: center; text-decoration-line: none; transition: opacity 0.1s linear 0s; vertical-align: middle; width: 1px;"></a></h2>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-vs___Length___-a_Address__" style="box-sizing: inherit;"></span><span id="-vs___length___-a_address__" style="box-sizing: inherit;"></span><span id="-VS___LENGTH___-A_ADDRESS__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-vs {</span> <em style="box-sizing: inherit;">Length</em> <span style="box-sizing: inherit; font-weight: bolder;">| -a</span> <em style="box-sizing: inherit;">Address</em> <span style="box-sizing: inherit; font-weight: bolder;">}</span><br />
Displays the virtual space operation log. <em style="box-sizing: inherit;">Length</em> specifies the number of records to display, starting with the most recent. <em style="box-sizing: inherit;">Address</em> specifies the virtual address. Records of the virtual operations that contain this virtual address are displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-hp___Length___-a_Address__" style="box-sizing: inherit;"></span><span id="-hp___length___-a_address__" style="box-sizing: inherit;"></span><span id="-HP___LENGTH___-A_ADDRESS__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-hp {</span> <em style="box-sizing: inherit;">Length</em> <span style="box-sizing: inherit; font-weight: bolder;">| -a</span> <em style="box-sizing: inherit;">Address</em> <span style="box-sizing: inherit; font-weight: bolder;">}</span><br />
Displays the heap operation log. <em style="box-sizing: inherit;">Address</em> specifies the heap address. Records of the heap operations that contain this heap address are displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-cs___Length___-a_Address__" style="box-sizing: inherit;"></span><span id="-cs___length___-a_address__" style="box-sizing: inherit;"></span><span id="-CS___LENGTH___-A_ADDRESS__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-cs {</span> <em style="box-sizing: inherit;">Length</em> <span style="box-sizing: inherit; font-weight: bolder;">| -a</span> <em style="box-sizing: inherit;">Address</em> <span style="box-sizing: inherit; font-weight: bolder;">}</span><br />
Displays the critical section delete log. <em style="box-sizing: inherit;">Length</em> specifies the number of records to display, starting with the most recent. <em style="box-sizing: inherit;">Address</em> specifies the critical section address. Records for the particular critical section are displayed when <em style="box-sizing: inherit;">Address</em> is specified.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-dlls___Length__" style="box-sizing: inherit;"></span><span id="-dlls___length__" style="box-sizing: inherit;"></span><span id="-DLLS___LENGTH__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-dlls [</span> <em style="box-sizing: inherit;">Length</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span><br />
Displays the DLL load/unload log. <em style="box-sizing: inherit;">Length</em> specifies the number of records to display, starting with the most recent.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-trm" style="box-sizing: inherit;"></span><span id="-TRM" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-trm</span><br />
Displays a log of all terminated and suspended threads.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-ex___Length__" style="box-sizing: inherit;"></span><span id="-ex___length__" style="box-sizing: inherit;"></span><span id="-EX___LENGTH__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-ex [</span> <em style="box-sizing: inherit;">Length</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span><br />
Displays the exception log. Application Verifier tracks all the exceptions in the application.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-threads___ThreadID__" style="box-sizing: inherit;"></span><span id="-threads___threadid__" style="box-sizing: inherit;"></span><span id="-THREADS___THREADID__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-threads [</span> <em style="box-sizing: inherit;">ThreadID</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span><br />
Displays information about threads in the target process. For child threads, the stack size and the <span style="box-sizing: inherit; font-weight: bolder;">CreateThread</span> flags specified by the parent are also displayed. If you provide a thread ID, information for only that thread is displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-tp___ThreadID___" style="box-sizing: inherit;"></span><span id="-tp___threadid___" style="box-sizing: inherit;"></span><span id="-TP___THREADID___" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-tp [</span> <em style="box-sizing: inherit;">ThreadID</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span><br />
Displays the threadpool log. This log contains stack traces for various operations such as changing the thread affinity mask, changing thread priority, posting thread messages, and initializing or uninitializing COM from within the threadpool callback. If you provide a thread ID, information for that thread only is displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-srw____Address___Address_Length_____-stats___" style="box-sizing: inherit;"></span><span id="-srw____address___address_length_____-stats___" style="box-sizing: inherit;"></span><span id="-SRW____ADDRESS___ADDRESS_LENGTH_____-STATS___" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-srw [</span> <em style="box-sizing: inherit;">Address</em> <span style="box-sizing: inherit; font-weight: bolder;">|</span> <em style="box-sizing: inherit;">Address Length</em> <span style="box-sizing: inherit; font-weight: bolder;">] [ -stats ]</span><br />
Displays the Slim Reader/Writer (SRW) log. If you specify <em style="box-sizing: inherit;">Address</em>, records for the SRW lock at that address are displayed. If you specify <em style="box-sizing: inherit;">Address</em> and <em style="box-sizing: inherit;">Length</em>, records for SRW locks in that address range are displayed. If you include the <span style="box-sizing: inherit; font-weight: bolder;">-stats</span> option, the SRW lock statistics are displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-leak___-m_ModuleName____-r_ResourceType____-a_Address_____-t___" style="box-sizing: inherit;"></span><span id="-leak___-m_modulename____-r_resourcetype____-a_address_____-t___" style="box-sizing: inherit;"></span><span id="-LEAK___-M_MODULENAME____-R_RESOURCETYPE____-A_ADDRESS_____-T___" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-leak [ -m</span> <em style="box-sizing: inherit;">ModuleName</em><span style="box-sizing: inherit; font-weight: bolder;">] [ -r</span> <em style="box-sizing: inherit;">ResourceType</em><span style="box-sizing: inherit; font-weight: bolder;">] [ -a</span> <em style="box-sizing: inherit;">Address</em> <span style="box-sizing: inherit; font-weight: bolder;">] [ -t ]</span><br />
Displays the outstanding resources log. These resources may or may not be leaks at any given point. If you specify <em style="box-sizing: inherit;">Modulename</em> (including the extension), all outstanding resources in the specified module are displayed. If you specify <em style="box-sizing: inherit;">ResourceType</em>, all outstanding resources of that resource type are displayed. If you specify <em style="box-sizing: inherit;">Address</em>, records of outstanding resources with that address are displayed. <em style="box-sizing: inherit;">ResourceType</em> can be one of the following:</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
Heap: Displays heap allocations using Win32 Heap APIs</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
Local: Displays Local/Global allocations</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
CRT: Displays allocations using CRT APIs</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
Virtual: Displays Virtual reservations</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
BSTR: Displays BSTR allocations</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
Registry: Displays Registry key opens</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
Power: Displays power notification objects</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
Handle: Displays thread, file, and event handle allocations</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-trace_TraceIndex" style="box-sizing: inherit;"></span><span id="-trace_traceindex" style="box-sizing: inherit;"></span><span id="-TRACE_TRACEINDEX" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-trace</span> <em style="box-sizing: inherit;">TraceIndex</em> Displays a stack trace for the specified trace index. Some structures use this 16-bit index number to identify a stack trace. This index points to a location within the stack trace database.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-cnt" style="box-sizing: inherit;"></span><span id="-CNT" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-cnt</span> Displays a list of global counters.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-brk___BreakEventType__" style="box-sizing: inherit;"></span><span id="-brk___breakeventtype__" style="box-sizing: inherit;"></span><span id="-BRK___BREAKEVENTTYPE__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-brk [</span> <em style="box-sizing: inherit;">BreakEventType</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span> Specifies a break event. <em style="box-sizing: inherit;">BreakEventType</em> is the type number of the break event. For a list of possible types, and a list of the current break event settings, enter <span style="box-sizing: inherit; font-weight: bolder;">!avrf -brk</span>.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-flt___EventType_Probability__" style="box-sizing: inherit;"></span><span id="-flt___eventtype_probability__" style="box-sizing: inherit;"></span><span id="-FLT___EVENTTYPE_PROBABILITY__" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-flt [</span> <em style="box-sizing: inherit;">EventType Probability</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span> Specifies a fault injection. <em style="box-sizing: inherit;">EventType</em> is the type number of the event. <em style="box-sizing: inherit;">Probability</em> is the frequency with which the event will fail. This can be any integer between 0 and 1,000,000 (0xF4240). If you enter <span style="box-sizing: inherit; font-weight: bolder;">!avrf -flt</span> with no additional parameters, the current fault injection settings are displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-flt_break_EventType" style="box-sizing: inherit;"></span><span id="-flt_break_eventtype" style="box-sizing: inherit;"></span><span id="-FLT_BREAK_EVENTTYPE" style="box-sizing: inherit;"></span>-<span style="box-sizing: inherit; font-weight: bolder;">flt break</span> <em style="box-sizing: inherit;">EventType</em> Causes Application Verifier to break into the debugger each time this fault, specified by <em style="box-sizing: inherit;">EventType</em>, is injected.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-flt_stacks_Length" style="box-sizing: inherit;"></span><span id="-flt_stacks_length" style="box-sizing: inherit;"></span><span id="-FLT_STACKS_LENGTH" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-flt stacks</span> <em style="box-sizing: inherit;">Length</em> Displays <em style="box-sizing: inherit;">Length</em> number of stack traces for the most recent fault-injected operations.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-trg___Start_End___dll_Module___all____" style="box-sizing: inherit;"></span><span id="-trg___start_end___dll_module___all____" style="box-sizing: inherit;"></span><span id="-TRG___START_END___DLL_MODULE___ALL____" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-trg [</span> <em style="box-sizing: inherit;">Start End</em> <span style="box-sizing: inherit; font-weight: bolder;">| dll</span> <em style="box-sizing: inherit;">Module</em> <span style="box-sizing: inherit; font-weight: bolder;">| all ]</span> Specifies a target range. <em style="box-sizing: inherit;">Start</em> is the beginning address of the target range. <em style="box-sizing: inherit;">End</em> is the ending address of the target range. <em style="box-sizing: inherit;">Module</em> specifies the name (including the .exe or .dll extension, but not including the path) of a module to be targeted. If you enter <span style="box-sizing: inherit; font-weight: bolder;">-trg all</span>, all target ranges are reset. If you enter <span style="box-sizing: inherit; font-weight: bolder;">-trg</span> with no additional parameters, the current target ranges are displayed.</div>
<div style="box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Segoe WP", "Helvetica Neue", Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; margin-top: 1rem; overflow-wrap: break-word; padding: 0px;">
<span id="-skp___Start_End___dll_Module___all___Time____" style="box-sizing: inherit;"></span><span id="-skp___start_end___dll_module___all___time____" style="box-sizing: inherit;"></span><span id="-SKP___START_END___DLL_MODULE___ALL___TIME____" style="box-sizing: inherit;"></span><span style="box-sizing: inherit; font-weight: bolder;">-skp [</span> <em style="box-sizing: inherit;">Start End</em> <span style="box-sizing: inherit; font-weight: bolder;">| dll</span> <em style="box-sizing: inherit;">Module</em> <span style="box-sizing: inherit; font-weight: bolder;">| all |</span> <em style="box-sizing: inherit;">Time</em> <span style="box-sizing: inherit; font-weight: bolder;">]</span> Specifies an exclusion range. <em style="box-sizing: inherit;">Start</em> is the beginning address of the exclusion range. <em style="box-sizing: inherit;">End</em> is the ending address of the exclusion range. Module specifies the name of a module to be targeted or excluded. <em style="box-sizing: inherit;">Module</em> specifies the name (including the .exe or .dll extension, but not including the path) of a module to be excluded. If you enter <span style="box-sizing: inherit; font-weight: bolder;">-skp all</span>, all target ranges or exclusion ranges are reset. If you enter a<em style="box-sizing: inherit;">Time</em> value, all faults are suppressed for <em style="box-sizing: inherit;">Time</em> milliseconds after execution resumes.</div>
</div>
<div style="background-color: white; color: #222222; font-family: "segoe ui"; font-size: 14px; line-height: inherit; margin-bottom: 0.5em; margin-top: 0.5em;">
<br />
<br /></div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-49668839880115258202019-09-25T14:35:00.001-07:002019-09-25T14:35:17.094-07:00Setting windbg to break in for C++ exceptions<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">Sometimes unhanded C++ exceptions will crash you program.</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">It might looks something like this:</span></span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">(fc0.5204): C++ EH exception - code e06d7363 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
KERNELBASE!RaiseException+0x69:</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">windbg has gotten a lot better at handling exceptions. A lot of times, you can just type:</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">> .excr</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">And it will reconstituted and set the context to the stack the threw; still, there are other factors that may prevent this from working like you'd want.</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">If that doesn't work, you can just use the trusty sx to set an exception handler</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">> sxe eh</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">Or if you have a specific structured exception number</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">> sxe number</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre><span style="background-color: white;"><span style="color: #1e1e1e; font-family: Consolas;">
</span></span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
<pre style="font-family: Consolas;"><span style="background-color: white; color: #1e1e1e;">
</span></pre>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-25520752747199631252017-11-22T11:51:00.002-08:002017-11-22T11:52:52.074-08:00How to Find a loaded Module in Windows<div>
Let's get right into it. Most of the time it is very easy where to find where a dll or exe is loaded using tlist.exe (aka task list). In an elevated prompt, type:</div>
<div>
<br /></div>
<div>
> tlist /m module.dll|exe</div>
<div>
<br /></div>
<div>
eg.<br />
C:\Debuggers> tlist /m cfgmgr32.dll<br />
C:\WINDOWS\System32\cfgmgr32.dll - 828 lsass.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1108 svchost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1132 WUDFHost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1240 svchost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1304 svchost.exe<br />
C:\WINDOWS\System32\CFGMGR32.dll - 1556 svchost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1652 svchost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1676 dwm.exe DWM Notification Window<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1940 svchost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 2016 svchost.exe<br />
C:\WINDOWS\System32\cfgmgr32.dll - 1348 svchost.exe<br />
...</div>
<div>
<br /></div>
<div>
I think generally though the idea is that you can use this to find the PID for debugging the component in question.</div>
<div>
<br /></div>
<div>
eg.<br />
C:\Debuggers> tlist /m notepad.exe<br />
C:\WINDOWS\system32\NOTEPAD.EXE - 12900 notepad.exe remote.txt - Notepad</div>
<div>
C:\Debuggers>windbg -p 12900</div>
<div>
<br /></div>
<div>
That is assuming that it is already loaded and running. What if it isn't loaded?</div>
<div>
<br /></div>
<div>
eg.<br />
C:\Debuggers> tlist /m hotplug.dll<br />
No tasks found using HOTPLUG.DLL</div>
<div>
<br /></div>
<div>
The easiest case is you know where it will be loaded. For example, you can know that exporer.exe will load it eventually. Then, you simply need to just attach a debugger to explorer.exe </div>
<div>
<br /></div>
<div>
eg. <br />
C:\Debuggers> tlist explorer.exe<br />
9020 explorer.exe Program Manager<br />
CWD: C:\WINDOWS\system32\<br />
CmdLine: "C:\WINDOWS\explorer.exe"<br />
VirtualSize: 2148226416 KB PeakVirtualSize: 2149576868 KB<br />
...<br />
C:\Debuggers> windbg -p 9020 </div>
<div>
<br /></div>
<div>
After that, you can do standard WinDbg stuff like setting a breakpoint:</div>
<div>
<br /></div>
<div>
eg.<br />
> bp hotplug!SomeFunction</div>
<div>
<br /></div>
<div>
Or, if you need to break it before the DLL gets fully loaded, that is a little more work:</div>
<div>
> sxe ld hotplug.dll<br />
> bp hotplug!DllMain</div>
<div>
> g</div>
<div>
<br /></div>
<div>
What if you have no idea where hotplug.dll gets loaded? That is where using a KD comes in handy.</div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com01 Microsoft Way, Redmond, WA 98052, USA47.6393225 -122.128383322.117288 -163.4369773 73.161357 -80.8197893tag:blogger.com,1999:blog-1650318142382098495.post-9478420327313446092017-05-11T14:42:00.002-07:002017-05-11T14:44:00.458-07:00Custom Capabilities for Windows AppsHere is a little update on what I have been working for the last release of Windows. As you may know, Windows uses the capability model. To mark app container apps with privileges to certain capabilities like using location, or a camera. The basic idea of custom capabilities is to allow 3rd party developers to define their own custom capabilities so that their apps or their partner's apps can similarly be marked. Ultimately a capability becomes a SID that is stamped on the app's token. Internal brokered components check those SIDs before letting apps do privileged things out of the app container sand box. Now 3rd parties can also have services or drivers that can also check for those SIDs before allowing apps to use their privileged resources.<br />
<br />
Watch the video below to get a more info:<br />
<a href="https://channel9.msdn.com/events/Build/2017/P4086">https://channel9.msdn.com/events/Build/2017/P4086</a><br />
<iframe src="https://channel9.msdn.com/Events/Build/2017/P4086/player" width="640" height="360" allowFullScreen frameBorder="0"></iframe>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-63672377827489837912017-02-03T10:35:00.000-08:002017-02-03T10:35:02.053-08:00Powershell Howto: Arrays of Stucts/Objects Using [pscustomobject]First off, I am not a regular powershell scripter, but I was writing a powershell script to automate some e2e (end to end) testing. I recently finished a feature in one our DEHes (deployment extension handler used for installing appx packages in Windows), so we needed a test for our nightly test passes. <br />
<br />
I wanted to make an array of appx packages that I wanted to test in different scenarios, I also wanted to keep track of other data in the element like expected outcomes for trying to deploy the app in various developer settings. In C, I would simply define a structure with the data I wanted for each element, and then define a static array of these structs for each appx package.<br />
<br />
In powershell, you can use a pscustomobject to make something like a C struct. Thy syntax is like this:<br />
<br />
$obj = [pscustomobject]@{name="good appx";canSideLoad=$true;canInstallDevMode=$true;path="c:\test\packages\test_app_1.1.34.0_good_appx\"}<br />
<br />
Now, to make that an array of objects:<br />
$packages = @(<br /> [pscustomobject]@{name="p1";canInstallDevMode=$true;canDevMode=$true;path="\\path1"},<br />
[pscustomobject]@{name="p2";canInstallDevMode=$true;canDevMode=$true;path="\\path2"})<br />
<br />
Aside: You can use a hash table if you have a two item tuple. The syntax for a hash table looks like this:<br />
$packagePaths = @{"case1" = "\\path1..."; "case2" = "\\path2...";}<br />
<br />
How do you walk the array of [pscustomobject] using a for loop?<br />
<br />
for ($i = 0; $i -lt $packages.Count; $i++) {<br />
$basePath = $packages[$i].path<br />
...<br />
}<br />
<br />
<br />samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-45395810571562625072016-04-14T19:24:00.002-07:002016-04-15T12:51:24.750-07:00How to Find a RPC Server's Clients Via WinDbgNeed to level up your Windows RPC debugging skills? Read on.<br />
<br />
I have been debugging a service stop hang. The simple conclusion is that my service had RPC clients hanging around. This is a little how to for how to use windbg to figure out who the offending client is.<br />
<br />
The first thing is obvious, the SCM is blocked on <span style="background-color: yellow;">thread 0</span> because my service main has not exited, so let's find that thread. Obviously it is thread <span style="background-color: lime;">1</span>. What is that thread blocked on? It is trying to <span style="background-color: lime;">close out its RPC server interfaces</span>.<br />
<br />
What is RPC waiting for? Normally it is outstanding clients.<br />
<br />
==========================================================<br />
0:001> ~* kn<br />
<br />
<span style="background-color: yellow;"> 0</span> Id: 1668.17fc Suspend: 1 Teb: 00331000 Unfrozen<br />
# ChildEBP RetAddr <br />
00 0008fc74 775bddba ntdll!KiFastSystemCallRet [d:\rs1\minkernel\ntos\rtl\i386\userdisp.asm @ 818]<br />
01 0008fc78 749533d0 ntdll!NtWaitForSingleObject+0xa [d:\rs1.obj.x86fre\minkernel\ntdll\daytona\objfre\i386\usrstubs.asm @ 217]<br />
WARNING: Stack unwind information not available. Following frames may be wrong.<br />
02 0008fcec 74953312 KERNELBASE!WaitForSingleObjectEx+0xb0<br />
<span style="background-color: yellow;">03 0008fd00 76b5214c KERNELBASE!WaitForSingleObject+0x12</span><br />
04 0008fdc0 76b5deb1 sechost!StartServiceW+0x1dc<br />
05 0008fe70 76b5102c sechost!RpcClientCapabilityCheck+0x851<br />
06 0008feac 00ab32c0 sechost!StartServiceCtrlDispatcherW+0x5c<br />
07 0008fed0 76aba954 myhost+0x32c0<br />
08 0008fee4 7759a16a KERNEL32!BaseThreadInitThunk+0x24<br />
09 0008ff2c 7759a139 ntdll!__RtlUserThreadStart+0x2b [d:\rs1\minkernel\ntdll\rtlstrt.c @ 997]<br />
0a 0008ff3c 00000000 ntdll!_RtlUserThreadStart+0x1b [d:\rs1\minkernel\ntdll\rtlstrt.c @ 914]<br />
<br />
<span style="background-color: lime;">1</span> Id: 1668.400 Suspend: 1 Teb: 00336000 Unfrozen<br />
# ChildEBP RetAddr <br />
00 0087f480 775c04ca ntdll!KiFastSystemCallRet [d:\rs1\minkernel\ntos\rtl\i386\userdisp.asm @ 818]<br />
01 0087f484 7495dc38 ntdll!NtDelayExecution+0xa [d:\rs1.obj.x86fre\minkernel\ntdll\daytona\objfre\i386\usrstubs.asm @ 2769]<br />
WARNING: Stack unwind information not available. Following frames may be wrong.<br />
02 0087f4ec 7495db8f KERNELBASE!SleepEx+0x98<br />
03 0087f4fc 76c111d0 KERNELBASE!Sleep+0xf<br />
04 (Inline) -------- RPCRT4!PauseExecution+0xb [d:\rs1\minio\rpc\runtime\mtrt\threads.cxx @ 88]<br />
05 0087f538 76be2609 RPCRT4!RPC_SERVER::UnregisterIf+0x2f996 [d:\rs1\minio\rpc\runtime\mtrt\hndlsvr.cxx @ 4838]<br />
06 0087f574 76be2318 RPCRT4!RPC_SERVER::DeactivateInterfaceGroup+0xf3 [d:\rs1\minio\rpc\runtime\mtrt\hndlsvr.cxx @ 11256]<br />
<span style="background-color: lime;">07 0087f5a0 69d78b0b RPCRT4!RPC_SERVER::CloseInterfaceGroup+0xe5 [d:\rs1\minio\rpc\runtime\mtrt\hndlsvr.cxx @ 10484]</span><br />
08 0087f5b0 69d7c04d my_svc!DestroyRpcServices+0x1b [s:\epix_dev\onecore\base\devices\my_svc\rpcif.cpp @ 540]<br />
09 0087f658 69d7ca5a my_svc!MySvcStop+0x27d [s:\epix_dev\onecore\base\devices\my_svc\srventry.cpp @ 198]<br />
0a 0087f660 77584eee my_svc!MySvcStopThreadProc+0xa [s:\epix_dev\onecore\base\devices\my_svc\srventry.cpp @ 350]<br />
0b 0087f6c4 77575cc2 ntdll!TppSimplepExecuteCallback+0x6e [d:\rs1\minkernel\threadpool\ntdll\simple.c @ 376]<br />
0c 0087f8c8 76aba954 ntdll!TppWorkerThread+0x902 [d:\rs1\minkernel\threadpool\ntdll\worker.c @ 1075]<br />
0d 0087f8dc 7759a16a KERNEL32!BaseThreadInitThunk+0x24<br />
0e 0087f924 7759a139 ntdll!__RtlUserThreadStart+0x2b [d:\rs1\minkernel\ntdll\rtlstrt.c @ 997]<br />
0f 0087f934 00000000 ntdll!_RtlUserThreadStart+0x1b [d:\rs1\minkernel\ntdll\rtlstrt.c @ 914]<br />
<br />
2 Id: 1668.1118 Suspend: 1 Teb: 00337000 Unfrozen<br />
# ChildEBP RetAddr <br />
00 008efc68 775bdd9a ntdll!KiFastSystemCallRet [d:\rs1\minkernel\ntos\rtl\i386\userdisp.asm @ 818]<br />
01 008efc6c 77575666 ntdll!NtWaitForWorkViaWorkerFactory+0xa [d:\rs1.obj.x86fre\minkernel\ntdll\daytona\objfre\i386\usrstubs.asm @ 209]<br />
02 008efe7c 76aba954 ntdll!TppWorkerThread+0x2a6 [d:\rs1\minkernel\threadpool\ntdll\worker.c @ 876]<br />
WARNING: Stack unwind information not available. Following frames may be wrong.<br />
03 008efe90 7759a16a KERNEL32!BaseThreadInitThunk+0x24<br />
04 008efed8 7759a139 ntdll!__RtlUserThreadStart+0x2b [d:\rs1\minkernel\ntdll\rtlstrt.c @ 997]<br />
05 008efee8 00000000 ntdll!_RtlUserThreadStart+0x1b [d:\rs1\minkernel\ntdll\rtlstrt.c @ 914]<br />
<br />
3 Id: 1668.dc0 Suspend: 1 Teb: 00338000 Unfrozen<br />
# ChildEBP RetAddr <br />
...<br />
==========================================================<br />
<br />
Lets figure out what is going on with unregistering the interface. So, we jump to <span style="background-color: yellow;">frame 5</span>. Well it looks like some of the locals are optimized out.<br />
<br />
==========================================================<br />
<br />
0:001> <span style="background-color: yellow;">.frame 5</span><br />
05 0087f538 76be2609 RPCRT4!RPC_SERVER::UnregisterIf+0x2f996 [d:\rs1\minio\rpc\runtime\mtrt\hndlsvr.cxx @ 4838]<br />
0:001> ?? RpcInterface<br />
class RPC_INTERFACE * 0x00000000<br />
0:001> dv -v<br />
@ebx this = 0x0087f4c8<br />
0087f540 RpcInterfaceInformation = 0x69d22450<br />
@edi ManagerTypeUuid = 0x00000000<br />
0087f548 WaitForCallsToComplete = 1<br />
0087f54c FromIfGroup = 0x005f4be0<br />
0087f518 cursor = 0<br />
<unavailable> RpcStatus = <value unavailable=""></value></unavailable><br />
@esi RpcInterface = 0x00000000<br />
<unavailable> fNewValidInterfaceFound = <value unavailable=""></value></unavailable><br />
<unavailable> Status = <value unavailable=""></value></unavailable><br />
0087f524 NullUUID = {00000000-0000-0000-0000-000000000000}<br />
<unavailable> IfGroup = <value unavailable=""></value></unavailable><br />
<unavailable> Address = <value unavailable=""></value></unavailable><br />
<div>
<br /></div>
<div>
==========================================================</div>
<div>
<br /></div>
<div>
But, the stack tells me that thread 1 is sleep spinning, waiting for something. Let's see what RPC calls are outstanding.</div>
<div>
<br /></div>
<div>
Looks like there is <span style="background-color: yellow;">MyIf RPC context hanging out still</span>.</div>
<div>
<br /></div>
<div>
==========================================================</div>
<div>
<br /></div>
<div>
<div>
0:001> !rpcexts.listcalls</div>
<div>
<br /></div>
<div>
RPC_SERVER at 0x5e3180</div>
<div>
&RpcAddressDictionary(RPC_SIMPLE_DICT) - 0x5e31b4</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>Printing 1 items in dictionary: 5e31b4 with 4 slots</div>
<div>
<br /></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>(0): 0x5f6e60 - LRPC_ADDRESS</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>Printing 1 items in dictionary: 5f6ee8 with 4 slots</div>
<div>
<br /></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>(0): <span style="background-color: yellow;">0x5f8c10 - LRPC_SMYIF_TYPE</span></div>
<div>
<br /></div>
<div>
0:001> !obj 0x5f8c10</div>
<div>
Dumping LRPC_SMYIF...</div>
<div>
<br /></div>
<div>
LpcServerPort(HANDLE) - 0x174</div>
<div>
Address - 0x5f6e60</div>
<div>
&Bindings(LRPC_SBINDING_DICT) - 0x5f8c34</div>
<div>
&MyIfMutex - 0x5f8c50</div>
<div>
&SContextDict - 0x5f8c68<br />
<br />
<div>
0:001> dt RPCRT4!LRPC_SMYIF 0x5f8c10 </div>
<div>
+0x000 __VFN_table : 0x76ba9500 </div>
<div>
+0x004 MagicLong : 0x89abcdef</div>
<div>
+0x008 ObjectType : 0n32768</div>
<div>
+0x00c RefCount : INTERLOCKED_INTEGER (0x1)</div>
<div>
+0x010 MyIfID : 1</div>
<div>
+0x014 CtxCollection : 0x005f1a80 ContextCollection</div>
<div>
+0x018 TableIndex : 0</div>
<div>
+0x01c LpcServerPort : 0x00000174 Void</div>
<div>
+0x020 Address : 0x005f6e60 LRPC_ADDRESS</div>
<div>
+0x024 Bindings : LRPC_SBINDING_DICT</div>
<div>
+0x040 MyIfMutex : MUTEX</div>
<div>
+0x058 SContextDict : LRPC_SCONTEXT_DICT</div>
<div>
+0x078 MsgNumbers : tagLrpcMessageNumbers</div>
<div>
+0x080 CloseMessageNumber : 4</div>
<div>
+0x084 IoTarget : tagLRPC_IO_TARGET</div>
<div>
+0x090 BindingsCollectionLock : RPC_SRWLOCK</div>
<div>
+0x094 <span style="background-color: lime;">ActiveCallsListHead </span>: _LIST_ENTRY [ 0x5f89ec - 0x5f89ec ]</div>
<div>
+0x09c CausalFlowsTable : GenericTable<lrpc_scausal_flow amp="" ompareflowid=""></lrpc_scausal_flow></div>
<div>
+0x0e0 CachedCalls : LRPC_CACHED_SCALLS</div>
<div>
+0x0f0 Flags : (0x0)</div>
<div>
+0x0f8 SectionCache : LRPC_SECTION_CACHE</div>
<div>
+0x158 PipeHistoryData : (null) </div>
<div>
+0x15c CancelHistoryInformation : LRPC_CANCEL_HISTORY_INFORMATION</div>
<div>
+0x170 CorrelationId : 0x1124cb</div>
<div>
+0x174 DisconnectNotificationEvent : (null) </div>
</div>
</div>
<div>
<br /></div>
==========================================================<br />
<br />
Lets figure out what outstanding calls there are for that context by looking at the <span style="background-color: lime;">active calls list</span><span style="background-color: white;"> from above.</span><br />
<br />
Let's take a look at the first one.<br />
<br />
==========================================================<br />
<br />
0:001> ?0x5f8c10 +94<br />
Evaluate expression: 6261924 = 005f8ca4<br />
0:001> !obj 0x5f89ec<br />
0:001> dt rpcrt4!LRPC_SCALL<br />
+0x000 __VFN_table : Ptr32<br />
+0x004 MagicLong : Uint4B<br />
+0x008 ObjectType : Int4B<br />
+0x00c RefCount : INTERLOCKED_INTEGER<br />
+0x010 pAsync : Ptr32 _RPC_ASYNC_STATE<br />
+0x014 AsyncStatus : Int4B<br />
+0x018 CallingThread : Ptr32 THREAD<br />
+0x01c ReservedNotificationsLock : CSpinLock<br />
+0x020 CachedNotificationInfo : RPC_RESERVED_NOTIFICATION_INFO<br />
+0x03c CachedNotificationInfoAvailable : Int4B<br />
+0x04!opj 0 ReservedNotifications : RPC_RESERVED_NOTIFICATION_INFO_DICT2<br />
+0x06c ActivityID : _GUID<br />
+0x07c DispatchBuffer : Ptr32 Void<br />
+0x080 Flags : SCALL_CompositeFlags<br />
+0x084 SubscribeInfo : Ptr32 NotificationSubscriptionInformation<br />
+0x088 ActiveContextHandles : ServerContextHandle_DICT<br />
+0x0a4 AsyncCallbackState : Ptr32 ASYNC_SEC_CALLBACK_STATE<br />
+0x0a8 Association : Ptr32 LRPC_SASSOCIATION<br />
+0x0ac SBinding : Ptr32 LRPC_SBINDING<br />
+0x0b0 DebugCell : Ptr32 tagDebugCallInfo<br />
+0x0b4 DebugCellTag : Int4B<br />
+0x0b8 RpcMessage : _RPC_MESSAGE<br />
+0x0e4 RuntimeInfo : _RPC_RUNTIME_INFO<br />
+0x0f0 ClientPrincipalName : Ptr32 Wchar<br />
+0x0f4 ClientRequest : Ptr32 _LRPC_REQUEST_MESSAGE<br />
+0x0f8 Response : Ptr32 _LRPC_RESPONSE_MESSAGE<br />
+0x0fc AlpcPortSection : Ptr32 Void<br />
+0x100 LargeReplyDataBuffer : Ptr32 Void<br />
+0x104 LargeRequestDataBuffer : Ptr32 Void<br />
+0x108 LargeReplyDataSize : Uint4B<br />
+0x10c LargeReplyViewSize : Uint4B<br />
+0x110 ClientId : _CLIENT_ID<br />
+0x118 ObjectUuidFlag : Int4B<br />
+0x11c ObjectUuid : RPC_UUID<br />
+0x12c CallId : Uint4B<br />
+0x130 SContext : Ptr32 LRPC_SCONTEXT<br />
+0x134 ActiveCallsEntry : _LIST_ENTRY<br />
+0x13c CausalFlowEntry : _LIST_ENTRY<br />
+0x144 CallCausalFlowNumber : Uint4B<br />
+0x148 AdditionalCallData : LRPC_SCALL::<unnamed-type-additionalcalldata></unnamed-type-additionalcalldata><br />
+0x14c SystemHandles : LRPC_SYSTEM_HANDLE_DATA<br />
+0x15c TokenAttributes : RPCP_ALPC_TOKEN_ATTR<br />
0:001> ?0x5f89ec -134<br />
Evaluate expression: 6260920 = 005f88b8<br />
0:001> !obj 005f88b8<br />
Dumping LRPC_SCALL ...<br />
<br />
AsyncStatus - 0x0<br />
pAsync - 0x5f21b0<br />
CallingThread - 0x0<br />
&ActiveContextHandles(ServerContextHandle_DICT) - 0x5f8940<br />
DispatchBuffer - 0x5fff78<br />
pMyIf(LRPC_MYIF) - 0x5f8c10<br />
pSBinding(LRPC_SBINDING) - 0x5e9a10<br />
ObjectUuidFlag - 0x1<br />
ObjectUuid - 49541cea-a719-4e75-8d58-a3a7bfff960e<br />
<span style="background-color: orange;">CallId - 0x2</span><br />
<span style="background-color: cyan;">ClientId.UniqueProcess(CLIENT_ID.HANDLE) - 0x730</span><br />
<span style="background-color: cyan;">ClientId.UniqueThread (CLIENT_ID.HANDLE) - 0x1580</span><br />
RefCount - 0x1<br />
SContext - 0x0<br />
<br />
==========================================================<br />
<br />
That is very useful. We now know the <span style="background-color: cyan;">thread and process ID </span>of the caller. You can now go crazy with !process and !thread. You can even use WinDbg to attach and debug the caller directly if you want.<br />
<br />
<span style="background-color: orange;">This </span>is also useful. It tells you which method in your interface it is actually calling. <br />
<br />
==========================================================<br />
0:001> !dict 0x5f8940<br />
<br />
Printing 1 items in dictionary: 5f8940 with 4 slots<br />
<br />
(0): 0x5e0a40<br />
<br />
0:001> dt rpcrt4!ServerContextHandle 0x5e0a40<br />
+0x000 ContextChain : _LIST_ENTRY [ 0x0 - 0x0 ]<br />
+0x008 UserContext : 0x008aad58 Void<br />
+0x00c UserRunDown : 0x69d6b930 void MySvc!HDMYIF_rundown+0<br />
+0x010 ClientId : RPC_CLIENT_TRANSPORT_SEC_IDENTIFIER<br />
+0x018 RpcInterface : 0x005f6580 RPC_INTERFACE<br />
+0x01c CtxGuard : CTXT_HANDLE_INFO<br />
+0x028 Node : GenericTable<servercontexthandle amp="" efaultcomparekeys=""> >::NodeType</servercontexthandle><br />
+0x04c UserStrict : 0n0<br />
+0x050 Lock : SWMRLock<br />
+0x064 OwnerSID : (null)<br />
+0x068 ReferenceCount : 0n2<br />
+0x06c Flags : 1<br />
+0x070 DeadlockTag : 0n0<br />
0:001> !teb<br />
TEB at 00336000<br />
ExceptionList: 0087f4dc<br />
StackBase: 00880000<br />
StackLimit: 0087c000<br />
SubSystemTib: 00000000<br />
FiberData: 00001e00<br />
ArbitraryUserPointer: 00000000<br />
Self: 00336000<br />
EnvironmentPointer: 00000000<br />
ClientId: 00001668 . 00000400<br />
RpcHandle: 00000000<br />
Tls Storage: 0033602c<br />
PEB Address: 00330000<br />
LastErrorValue: 0<br />
LastStatusValue: 0<br />
Count Owned Locks: 0<br />
HardErrorMode: 0<br />
0:001> dt rpcrt4!LRPC_SCALL 005f88b8<br />
+0x000 __VFN_table : 0x76ba9150<br />
+0x004 MagicLong : 0x89abcdef<br />
+0x008 ObjectType : 0n8192<br />
+0x00c RefCount : INTERLOCKED_INTEGER (0x1)<br />
+0x010 pAsync : 0x005f21b0 _RPC_ASYNC_STATE<br />
+0x014 AsyncStatus : 0n0<br />
+0x018 CallingThread : (null)<br />
+0x01c ReservedNotificationsLock : CSpinLock<br />
+0x020 CachedNotificationInfo : RPC_RESERVED_NOTIFICATION_INFO<br />
+0x03c CachedNotificationInfoAvailable : 0n1<br />
+0x040 ReservedNotifications : RPC_RESERVED_NOTIFICATION_INFO_DICT2<br />
+0x06c ActivityID : _GUID {00000000-0000-0000-0000-000000000000}<br />
+0x07c DispatchBuffer : 0x005fff78 Void<br />
+0x080 Flags : AssocClose+0x8000 (0x8800)<br />
+0x084 SubscribeInfo : 0x005f5ae8 NotificationSubscriptionInformation<br />
+0x088 ActiveContextHandles : ServerContextHandle_DICT<br />
+0x0a4 AsyncCallbackState : (null)<br />
+0x0a8 Association : 0x005f8c10 LRPC_SMYIF<br />
+0x0ac SBinding : 0x005e9a10 LRPC_SBINDING<br />
+0x0b0 DebugCell : (null)<br />
+0x0b4 DebugCellTag : 0n0<br />
+0x0b8 RpcMessage : _RPC_MESSAGE<br />
+0x0e4 RuntimeInfo : _RPC_RUNTIME_INFO<br />
+0x0f0 ClientPrincipalName : (null)<br />
+0x0f4 ClientRequest : 0x005fff20 _LRPC_REQUEST_MESSAGE<br />
+0x0f8 Response : 0x005ecd70 _LRPC_RESPONSE_MESSAGE<br />
+0x0fc AlpcPortSection : (null)<br />
+0x100 LargeReplyDataBuffer : (null)<br />
+0x104 LargeRequestDataBuffer : (null)<br />
+0x108 LargeReplyDataSize : 0<br />
+0x10c LargeReplyViewSize : 0<br />
+0x110 ClientId : _CLIENT_ID<br />
+0x118 ObjectUuidFlag : 0n1<br />
+0x11c ObjectUuid : RPC_UUID<br />
+0x12c CallId : 2<br />
+0x130 SContext : (null)<br />
+0x134 ActiveCallsEntry : _LIST_ENTRY [ 0x5f8ca4 - 0x5f8ca4 ]<br />
+0x13c CausalFlowEntry : _LIST_ENTRY [ 0x0 - 0x0 ]<br />
+0x144 CallCausalFlowNumber : 1<br />
+0x148 AdditionalCallData : LRPC_SCALL::<unnamed-type-additionalcalldata></unnamed-type-additionalcalldata><br />
+0x14c SystemHandles : LRPC_SYSTEM_HANDLE_DATA<br />
+0x15c TokenAttributes : RPCP_ALPC_TOKEN_ATTR<br />
0:001> dx -r1 (*((RPCRT4!_RPC_MESSAGE *)0x5f8970))<br />
(*((RPCRT4!_RPC_MESSAGE *)0x5f8970)) [Type: _RPC_MESSAGE]<br />
[+0x000] Handle : 0x5f88b8 [Type: void *]<br />
[+0x004] DataRepresentation : 0x10 [Type: unsigned long]<br />
[+0x008] Buffer : 0x5fff78 [Type: void *]<br />
[+0x00c] BufferLength : 0x1c [Type: unsigned int]<br />
[+0x010] ProcNum : 0x2 [Type: unsigned int]<br />
[+0x014] TransferSyntax : 0x5f65c4 [Type: _RPC_SYNTAX_IDENTIFIER *]<br />
[+0x018] RpcInterfaceInformation : 0x5f65ac [Type: void *]<br />
[+0x01c] ReservedForRuntime : 0x5f899c [Type: void *]<br />
[+0x020] ManagerEpv : 0x0 [Type: void *]<br />
[+0x024] ImportContext : 0x404 [Type: void *]<br />
[+0x028] RpcFlags : 0x9000 [Type: unsigned long]<br />
0:001> dx -r1 (*((RPCRT4!_RPC_SYNTAX_IDENTIFIER *)0x5f65c4))<br />
(*((RPCRT4!_RPC_SYNTAX_IDENTIFIER *)0x5f65c4)) [Type: _RPC_SYNTAX_IDENTIFIER]<br />
[+0x000] SyntaxGUID : {8A885D04-1CEB-11C9-9FE8-08002B104860} [Type: _GUID]<br />
[+0x010] SyntaxVersion [Type: _RPC_VERSION]<br />
0:001> dt RPCRT4!RPC_CLIENT_INTERFACE 0x5f65ac<br />
+0x000 Length : 0x44<br />
+0x004 InterfaceId : _RPC_SYNTAX_IDENTIFIER<br />
+0x018 TransferSyntax : _RPC_SYNTAX_IDENTIFIER<br />
+0x02c DispatchTable : 0x69d22444 RPC_DISPATCH_TABLE<br />
+0x030 RpcProtseqEndpointCount : 0<br />
+0x034 RpcProtseqEndpoint : (null)<br />
+0x038 Reserved : 0<br />
+0x03c InterpreterInfo : 0x69d22424 Void<br />
+0x040 Flags : 0x4000000<br />
0:001> dx -r1 (*((RPCRT4!_RPC_SYNTAX_IDENTIFIER *)0x5f65b0))<br />
(*((RPCRT4!_RPC_SYNTAX_IDENTIFIER *)0x5f65b0)) [Type: _RPC_SYNTAX_IDENTIFIER]<br />
[+0x000] SyntaxGUID : {850CEE52-3038-4277-B9B4-E05DB8B2C35C} [Type: _GUID]<br />
[+0x010] SyntaxVersion [Type: _RPC_VERSION]<br />
0:001> dx -r1 (*((RPCRT4!RPC_DISPATCH_TABLE *)0x69d22444))<br />
(*((RPCRT4!RPC_DISPATCH_TABLE *)0x69d22444)) [Type: RPC_DISPATCH_TABLE]<br />
[+0x000] DispatchTableCount : 0xe [Type: unsigned int]<br />
[+0x004] DispatchTable : 0x69d217bc [Type: void (**)(_RPC_MESSAGE *)]<br />
[+0x008] Reserved : 0 [Type: long]<br />
<br />samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-28719302983007690472015-09-08T17:43:00.001-07:002016-03-11T10:34:16.916-08:00WinRT ABI Debugging WorkflowVS can debug a WinRT app's code, but how do you debug the actual ABI? Here are some handy tricks to deploying and testing the ABI.<br />
<h2>
Setting Up the Test Box</h2>
For my systems programming, I like to have a development machine, and a separate test machine. This should be obvious, but yes, you can hose your development machine by replacing system binaries with modified ones. At this point, many of my coworkers simply use VMs. These days, you can grab a VHD directly off of the build share, so you don't even have to install the OS anymore. Maybe I am old fashioned, but I actually like to have a physical PC to test on. Generally it is faster and more reliable. Furthermore, I have less distractions, so I can debug faster.<br />
<br />
<b>What you need to install & configure:</b><br />
<ol>
<li>Install a correct build of the OS.</li>
<li>Install WinDBG. I guess it is part of the <a href="https://msdn.microsoft.com/en-us/windows/hardware/dn913721.aspx">WDK</a>?</li>
<li>Copy over the symbols locally. I think you can also get these from the WDK? You can also try to rely on the symbol server.</li>
<li>Set you PC to "Developer mode"<br />Settings->Update & Security->For developers->Developer mode<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUEFtu14wUOq9S2U9AptzxWjZXdp0RQCYikaH66pCxne7krWZA6tSugeoAMUCWJ9XZF-cWcDq3eCQKyOWTh0S5HMgd3UQZIe-0zXnnoYqVncxYBv1Xzy3gIrwQg9o8IQpyPh-Af-MYthA/s1600/developer+mode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="496" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUEFtu14wUOq9S2U9AptzxWjZXdp0RQCYikaH66pCxne7krWZA6tSugeoAMUCWJ9XZF-cWcDq3eCQKyOWTh0S5HMgd3UQZIe-0zXnnoYqVncxYBv1Xzy3gIrwQg9o8IQpyPh-Af-MYthA/s640/developer+mode.png" width="640" /></a></li>
<li>Install <a href="http://www.microsoft.com/en-us/download/details.aspx?id=48155">Remote Tools For VS 2015</a> : <a href="http://www.microsoft.com/en-us/download/details.aspx?id=48155">http://www.microsoft.com/en-us/download/details.aspx?id=48155</a></li>
<li>Run the remote debugging configuration:<br />Start -> All Apps -> Visual Studio 2015 -> Remote Debugging Configuration -> Remote debugger<br /><br />Click "Configure remote debugging"<br /><br /><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAakAAAG2CAYAAADFrHkVAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAFiISURBVHhe7b0PkGRHfef5EwZkLQI1y7/R+o+gemZa7hbgbTRztgATmKuegVJcuLhovCf2TAdna6bHsU3ZeOa2J7ggiCCmHTM+aOaI+SMuuAYHilg6ws3tqUDTtZggwCw7I/UarC6re6YbCWyDBNgNCAshzFz+8mW+yvcq8/2rqq6s7u9n4k2/ly///PKX+fKXme9V5g179uy5TgAAAICHSCP17W9/W10CAAAAfnDrrbfSc9Q5AAAA4B0wUgAAALwFRgoAAIC3wEgBAADwFhgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADQFW644QZ6+OGH1VU7fI/95CGjkfocHRERc+T6OPI5dctL2uV9/UeuqXtJcLjXUyav3eDaR+j1PUnvGn3k9Ub+X/8R4dIhnzvSiqtncmegn2kDABJ56KGH6Ddf/waroWI3vsd+csHLIqXz2ev30l3X56/qy3uvE90rXLeDWNqZiIfha7pO96ZJXCQtz7g6f/0ukddIVoXbfEeFFegvVX09YQeUCQC7CGGErj/vxl+UfzU2tyywfSo23ffW36F76RFaH5je7Fvp4tV5uuu+z4ix0k5GjKDeVaM7PnudLr5VOTF730PvMa8LcReN7lOnAADg4HWvex3917/6cjii0iModuN7eSlmpD73GbrvrndQZa+6llMwenrpiDIEaursc617PEV47SOvV/5iU3CROPR0IsfxNrqPvkK1fcJdzzFa00thb4Xecdd99BntOSmOq617LRnjU4GxayO+13/kIxnvmXGo84+oaTXpN0wsOX7NtTp9+iv30u8kGaRIvs1pW1f67N4qg5abkX6m/DHmdXB+5AjXh0D/nzvSkiso62jaLTd72nyk5wcA0GtMQ9WJgWJyGCnVUPAD/5nfoet/9R4KbJRoDPZ9mt5x9TqJ0Rld/yzRB8PGQIT5INEnpPu9dN/bbqB30SeUv3vpK7UzsnEK4ghGAPKeGPU88jZuiMQISER4r+jFz3P8cniQlF5WMsos5KDau4xG1kVU/k/Qp0XDqkm6F0ek3RS6lTK59ZMYx12j5B7wRONp6VndtqYfLYO/eo/umWjy5C/OV+iRUa4PF0UqYrx7UcnF6d33QUf5mxTJDwBgkMhhpFRDEZ82u7ZOj3BjoA3Y20S/t3lV3RRhPqGMmZwivIveoYdf5pShjMMYAex9D73v3q9QGI1JYnppqCmrrDInyWHC8d01T8eV/Hvf8z6RG0XSvTZE2tpjXD9Z4/hKk5ziynwn6dmRfhK58hfHqA+M/jhDjp4y0Iv8AAA6xpziM6f+ipB/uk80BJ+YfyQ2ermXPit7wOpo6/F2mwLpyamwO2h/2CZmieMarT+iTgeB+JTmIMHTdm8jVSZXaf4u5Q4AGCji76Di76jyUuidFPeW79DTYHv30x2i35t/ys1AxWG+L/rgfY53K4XS09NCwbRSchxfoU/XlXvkHc8+Gr3L6KXzezl1KuP7So3OKPmvfeSD2e5lJXMce+k97wumVVvvZgRCnx/ha5XvTHrOSqJsCTqLc7VJX9FTlVLv0jWZXuQHAFAY10cSnRiqYh9OiKb+uHxdw7+/Cb6co9o+NVUjjkgLmYUgjkdE4yrDy/dFyqCI/3/nXjU1J+PNmp4xnXfDB2n0qvnFW1Icd9EdzXcFbqZhMwyAvPcZHotpRHzqnRvfexe9I+O9rOSI460X1bsZJScf7yKqyEwE+bbruShJsiXpLMZbj9M81WiflLdJd4QjqXj5m/QiPwCAotx5551tBkqjDRX7yQO2j+8FPHW1r0nvUx8EREi6l5VuxNErfJYNADBQYPv4HvG5M7XW1FWMpHtZ6UYcvcJn2QAAgweMVFeILkP0tvvupc+Gn+gn3ctKN+LoFT7LBgAYdDDdBwAAwEsw3QcAAMBrYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFvk7qUcffVRdAgAAAH5w++23YyQFAADAX2CkAAAAeAuMFAAAAG+BkQIAAOAtMFIAAAC8BUYKAACAt8BIAQAA8BYYKQAAAN4CIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFhgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLQNlpJ7/3fvlAQAAYHcwUEbqxr/7U3kAAADYHQyMkeIR1HP+5ZvywGgKAAB2BwNjpHgEdf3FJA+MpgAAYHcwEEZKj6J+/q9JHn0fTW2ep4mJ87SpLnccafnzMf+9lmk35rlRo6GhIXnUGsoNdBcf65VnDISR0qMoKa04tnM0pR9S85g4u6buegoqfn/oRO/elVmDapNNmlvZoq2VOWqe6bFsZv67oQuv9LlJ5yfa25GBaEs8wHsjZY6iNNs5mtraCh7SgwfnaIXPxbE8M6LuArBD2bxGTRqlvSVxXpqm5eVp4tNtoRvpbbfMiZRoejloO9CW5Md7IxUZRWm2eTTl4lKt1SMKp0O4Bxf2lCbofLwrp3p452XYmuivKrd4GOmvRjXVA6s1Wr0xe1oqLu61HZ2ly5dnaVy4T3BkaTIxpp9xEV45u8Ou0dmwd2jKbPRezetIPOLI5R6NP6K7GLYy2Tw/EbqZeYi4m3JrTBlSdZJH72KUErqrss0a1iVThHj8wikSn1HvQn0afjm8jHuBJnWYpPJS8YTZ09eR+IM07WURy3+t1oovkl6a3AaGTLZybnMz/EvM64gMOepPDgq1JbsEr42UbRSl6fu7KfFArVVU72hxihbkdAg/3Gt0XPWStlaqtHTUUnnDsPNUTgpzuUkjF4Qbxz95lEifh2nN0uhiEG5lrkmTsnaLXtuFVm9teXojg0zRuGRvL3RPkU24C+80a8tnSFL8edM1dRfDWibcqV4O3KT7KM2eFXoSDcDR2VFaVO6Lo2u0EcSiyCtbVr1zZ2OSRMKBuzjmy1nDumQyscUfDdeqKwKrzso0z3HrHn9qeSUQKy9rWcR1F44u8sptwVbOqWVv4ijvXHGkYM2LI10VZDfhtZGyjqI0/R5NiQdqRreSwyPBwyqnSIzep3jALl+2VF4zbFKYg1U6xPMVHL95zvc4nBFP6VCVDi7URdWOkUWmWFwhWWQTyLRt+dQkxZ87XYt/jXlP64kxe6STC0TNa7RZ2kujMo2gd16ejxm9IrKZuPxtXqIlSsgD4wzrkMnEFn8sXKSuuHRmI0v6ceL+bWWhbrXRDblt5ZxW9iaussgTRxq2vLjSlZ52F94aqaRRlKbvoykbosLJ3md4ZKi8RcLkoZP4uyHbxpp9WsrlznRLJ9woji9RlT8A4HjC3r8YLch4K1SXDYGaSspCVtn6rfduk1ReWXCWRS+xlXPOsreWRQf1Jys+1oE+4K2RShxFafo9morDvSsxdJczGFkpEoaJhdu8tESXpyqtSqx7XVnil36W6JLq0sq4+CSjbJG0jd5eGE+5QlNG/CEu96I6cWGM+kKZRINZk5P83Nis0NzBJl0z5SiqkzS9lw5RlRzhU8M6ZDKxxR+LL1JeeXCVF2Mrdxu2stAYcUi6IbetnBsWN07YlgdXWbjqDxvibhgsV7q7EC+NlGsU9dzbgsPEr9GUqLCid9ic5J6VOlJfqBYJw0TDjfP8+Lx6fEvTdHwqmCqYOD+cIX4RF78fGA/uH10bbY02XGHFA8QvudltfKlKK5y2SPcCvzdQ7pF4jPjl1EWaeyGdWGBdjLZkDWUSjYBIWMU/TkvVCzStGs+AAjrJpPfg/YvpHrxKzBLWJZOJLf6ozJG6koto+mF5Ocs9hqssGDP/4WfZXZDbVs5lm1tC3bWVRWr96RRHuurubuKGPXv2XH/00UfVpR+88L+/hm54kTBSL1UOCm2gfvZ48FfznO+JEdUPf5V+9G+/rlyA1/CPROsV2oo3OC534CcoL9Bjbr/9dv9GUlneRcXx8t0UiNAwPrEd4o/PVMPmcgd+gvIC2413IynXKIpxjaQYjKYAAGBn4d1IqsgoSoPRFAAA7Dy8MlKZvuhzIcL07Eu/tIU2+Ysefqmp/yrngWenLTC608onjW7l1we9FZXBFq5oXNvxPPiga8/wxkh1MorS9GY01WgttLnFv95Xzr3Aqwpq5Ju/MnL9or9bmHnHg9pbBlm/fZO9h+0A6nsi3hipjkZRml6MpuQvv9VCm72m5NGimGa+t1sun/QA/KJfdWM72wEQwQsj1Y1RlKbboyleOyxcaJN7O9zrUUP+xF+Z2/yZPSZ5X4fn9dbEub6v/loX0IzEKw5rD0z0+gw/MmwkXFSeHbnAqCSmh0uBa+ZFaJPSicglDqu8GRcjzZyOschoFvfwd2cmMV1zwEhcuk7GsSwozLjkMHDrtrWAMh8yzy53jbyfrOuIu1UHTJ78xJ4HTj/iz1YvDbe2+Exi5aF+I4YFZ1t4YaS6MorSdHk0xT+oCxfaXN5LZ0VltS54GSGo1G3+5K/Ig1+18y/aR6eI6jL4hnhkRmiYTzWi0toXnUxb4BMLjAZY9HBIODvC2eVy+Xfpgd0LLkbqTMe10GzRBWhti9k6dGxiXVDYJUcUt25bcco8T6qG3eUeoRMdCHLlJ/Y8JLUDkfqeRT+Wup+rLux8+m6kujmK0vTm3ZSAh/yiMlkXvDRx+itTZSpYPmVjbZQqokI22Uqx/9G90SkMI7xrUVkrWGA0wLWQqyucSy6bf5ce2N22KCh3TqR70NhaFyN1pWOLL8ndJlcSsTDOOm1bUNglR+CthVO3rTjlkksiNrk8kcvdpFMddJSfBJ2ZaWeNL44ZR1pdkJ52Nn03Ul0dRWm6PJrqJqLO0dpGg+pNMXLiddaaonJvrNFoJe2pEnS6wGenDOQCoxnIK1fuhXFFT1yed3ExW5f7dpMmRy/LvBc66Hac3YzPlzLfZvpqpPKOovhHvLYf8troyWhKTtdlWPAywR/3uujMGWpWD4mRU4n4sl4nGonM9TlIWuBTgwVGA5IWcrWRJFcclx5i8oaIhjpxMVsXrvgS3VMWoNVoXRfQcejHJUecLLpt1GmB/cWfA5d7N3SgyJ2frDrLGh+TNirKE9cOo69GqiejKE1PRlPRRR/dC14m+BOVjZ+aqnpq+XJBjKr0Q5yMiNe2wGcELDAaYNGD+nCijSS5rLjKISqvPPglOxdyocVIHfEluRtyJZaDYzFbp45FA6n1Ey4o7JTDIEm3RpxyiSX91Z7LPUKHOiiaH0nUX9Z2wBmfte7HySrbzqNvyyLxCOemx4/Rv3APKaORSloWycrPiX5BdE+evu0c/fRl9yjHHUS/F/jEAqMB0EN+eBqQN5uOGyCXO9iV9HVZpJ6OojQ9GU31l34v8IkFRgOgBwC2h76MpIqMogqz00dTAACwQ+nbSGpbRlGaHTiaAgCA3cK2Gyn5Rd9Pv0nXf1EM4/55ew5Oi9Ps+Es/ni9PelmZdh/0BugdgB3LthspPaJ5zt+J45vbdIi0GIymAABgsPBy+3hvSfvyCF8m9QfoHYAdiZfbx3sHN4D6Ky7zd0mme2SxR8vClezXnI4yryPxiCOXezT+yMKWERptC87mXlBVI/24FgZNWlzTlKtdnqhfQ59Z3K2/FwMA7ARgpFLItZAo37IuXOmC43HFnzddc2FLE9uCs/z7wTwLqsZwLgwaX1zTtginawFcW76S3G36AQDsNGCkUsi1kCjfM5aACReuDC7biS1UGZLk7kzX4p9xLbRqjkTSFlSNY+QxujCoETaWh3ARTtcCuLZ8Jbm78gsA2FHASBVFNJIdL/boWqg09wKmOWED5dtCr658dSO/AICBBUYqBetilRkXe4wsPGmMqMJ4XAuV5l3ANAnXQqtZFv3MQsYFQENdZFgANyTR3bGIqBwh5lhlHADgNTBSKdgXq0xY7FE0qm0LV5ZcC7CKeFwLlbrcXek6sSy0upF3QdUYRh6zLgDaWoQzfQFcech8JbhnWUQUADDw4BN0n3AtVOrTAqY8UsHn3gCAbQCfoHuAa6FSLGAKAAAYSQEAAPAUjKQAAAB4DYwUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFhgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLTBSAAAAvAVGCgAAgLfASAEAAPAWGCkAAADeAiMFAADAW2CkAAAAeAuMFAAAAG+BkQIAAOAtg2mkNs9RuXyONvVf5dxTtjOtIvguHwAAFKAnRqo8NERD8qhRQ7llptPGNh6er4fKdC50aFCN5fKtUc8qt7oqjIxXl88QlVsJFKenutykc2Uha5tuWnkI61nEvQu6AgD0nZ4YqcbKKTpw4BStbM1TWbltG6V9NHZlnTbU5eaDS0QHiNZDh6u0emA/DZeOUaNxjErKue9klVtdFkMYuvElqq5s0dYWH4s0FibQAb3U5eaDtERT4t8SPWhaQVm/VD4WiSbZiLEc/ax7AICu0/vpPtXLPldr9Xxrqou7ea4cugU9ZdFrPnKSrlw5SePCjXv5ET+RkYWLMlWmVumq8rexPkYnTozRasuBqHqYSrr3nyBfpGc+LuRSztYeu44vvK978jwSCM7b82uSUW4+j6Rv6mSdzvKoo83dZIz2hdakTPPzqim3xanyFOhG5CGSL8Y2KmU3HY/SpUPeZH0ESGNdnaHK2BVailgpg3KFpgwDDwDYOdywZ8+e648++qi6TOd73/ueOmvnpS99aXDCjdIRoovcu+Zz0cCPLW6RbA8bNRo6vZ9WLhIdGV+nE6rH26jVSLSYVDbDysgMOGy9QlszVwM/HIfFLzd+R+giCWfRwD5Ih+f3icb7Ks0Ihw3R4NYrQpZhlY6UwyJfQ4QZmiTS7qFcUXdOa3z9BIlsiMa5ThVxMizczgojQ5V54Uc02py2K78ssCKT3ByfSkeG1XLJ+HmU1KBjQhlSrqWqyEdUNw0Rz+SCOJlaFDLr1JPiNHQj4PCBHPIiWh6Nw/RgeZzWT7T8J8edrA/hWRh4GTEd29DlouqUdA7yFslr7J4mqd4CAPpPaD8Mbr/99mJGyhZZBLOhiDca4XXQ2C/QlGjvjcbJ5t8cxfBUDjdw7Ef/jTVIMszZfdTgxpP/zg+Lxu4s7WvM0FX5V6Sn04nHUcRdNbbCGtHVmQbtOysa3Jn9dDoiAxsxS35Nsspt6kMi4lwR6TnksqbFBoatFRsrTi9LnIw2TMIKNVR+j5FDN4xL3q0K1bPoI4yPjd1p2s9GmNOL1wkz33EZAABe47IrbKT6+HVfmeblOwVurHjKx5xGUsgGzniHwu8b1K1E+P3OQp0aG+s0VuHmr0SHq0RXNzdonTp9r+NmeD+/Q2pQfZXfeR2m6qopQ4b8ZpXbfB8jD0cjn0R5XoRbpClOj6+zxlmeoVOcL/Gvvlqlw1ksgTXudH3wVJ+e+h2SBs2Y8jPjhEECYMfSPyMlDFBNvpzgxmqFTh1ovY8h8/3CgVZDKBut4DSF4P3O6dOrtF+17KL9p6Ujp2lVv9dJQ37I0HpZH6Yt3U/SWdWiSvepimzQS2xRTus0AgNTr1MgQ1J+QzLIHUvfhSlXCBv98IWbIPyIJFucAZyvVarX6u26ZMNMsXhccafqY5MeXLoiBnrasIljcYquLD1ofXcFANiZ9OYTdJ6KkT1gy2hBw63vyfHgpfnQOC1VL8p3Kfyl2ImpBZoU7uUHD9OJMd2THqIj62PZRlICHtVcEU1m2NOXDldorPXVQAqi8VwcEyLG0xbuYkS3Ohm4j58co0X9AobzJCxZVSXKlwtiVCUvXfmNkS53NH156I8OpM6VXPyOpvViKECO7iZb4XiUepFHIQlxWmBjvLpAdKItAyU6djEaT63hiDtNH/KrvlM0Y2ZBfiAhOg6uLyTkyDtD3QMADAy9eScFAAAAZMTTd1IAAABAMjBSAAAAvAVGCgAAgLfASAEAAPAWGCkAAADeAiMFAADAW2CkAAAAeAuMFAAAAG+BkQIAAOAtMFIAAAC8BUYKAACAt8BIAQAA8BYYKQAAAN4CIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEj1g81zVC6fo0116R2+yzfo9Eq/vpSbliOvPKh3wIL3RuoHP36G7v/SOh2774t096kHaOj3/u/IwW58j/2w324TeWj4IRoq07nQoUG1oRo1fHu44vK45FZXhZHxDtGQOsqtBIrTU11u0rmykLVNN608DGm9RNxjuuqpjNtE0TzshLyDgcJbI8UGh43Pa977n+jYn/813b92A335J68kGpkgGq0EhzhnN77HfqRfEaabxmrsyjptqPPNB5eIDhCthw5XafXAfhouHaNG4xiVlHPfKe3LJre6LIYwdONLVF3Zoq0tPhZpLEygA3qpy80HaYmmxL8letBsZQ+cohWZB3EsEk1yI8xyrJyiA/LePJWVV4lv5V2EnZAHsCvw0kidv/SINDj3P/I0/eCX3iAeqDcSvWwf0b96CdEvPE/5EvA5u/E94Yf9chgOy3F0g8rUKl1VDdrG+hidODFGqy0HouphKunepfp7rtbqmdd0F5zv6Z75+Em6opytPXaztyrv6548jwSC881z5TCNyMhAUs4mN59H0jdHW+t0lkcdbe4mY7QvbOXKND+vmnJbnCpPgW5EHiL5YmyjUnbT8ShdOuRN1keANNbVGaqMXaGliJUyKFdoyjDwVgwZ09KN3I/rMa4T7Wbx74zH9B/Wq2DEGNY9qUd72kl1tj1vIt4jIo0rJ2lcuPHIOTF/Jo582eUHoIVXRkqPnmY//TX6wcvHif7Na4med5O6mwH2K8JwWI6jG6Oq4f2kGrRNukpi9CEasbGlB2Vj1Kgv0FirlQ4QD/B6RffKp2jhND/cPOo4SWOLyp176NJz1H3l1CpNcgthjIS4YR2bIqrLhmNDmA4hg3iwj5wco0XV+18ca29Us8nN6a/TCRXP1kqVlo6ohvbKKu2/qOUiOqndQ9gQLtAkNy6t1lCQFKfWjRiZiJ78CRE+yJegUaeFqYoxYuGGdpJEJoN4xDFfdsSdQR8cn7RRh0vCDk3RFaWLOJvnTtNC1lFmhnRLxxqh/FuLY3TyrKkrgamTBN3Z44nWn1a9KtGxE6LuaeVK3Z6gY65hk63OWvMm4r2oR5db1BARpuZP4sqXS34AWnhjpNiY3D1Xp/sfekKOiuQIqSgcVsTBcXGcnRiq0uFqME8mp4r2icd0WDT5/MCKxn91iiqReSCBeIBntJuwFPKhk9Nrhrsm5s5pHVioi0e3NRLiUVBlZj+tcoPD/seEDGzEiA1E0Psuz8emowSZ5Ob4ZDxGT1aPIg5USbTnEimXZXRRnleNS6UehGdjlRhnVAdsLHRD2qiv0inzppQ7pjNX3Bn0EcSn8iRHS8aUnxoZcJzjS1VayToNlildY6QwuUBiOBs1jqZOknRni4f92+oVw3mUdYl1u0BTbRXVwIxD19kseWPS8se48pUkPwAKb4zU7Ke+Sn/z5M+IbvuN6JReUTgOERfHyXEXhh9Wftg31mlMPugl4vb/6qYa1QS+ug6PhNY3GlRfFWmUDlN11ZShTPOyV1qhunzw1VSRSVa5RSMRvo+Rh6MxSqI8L8Itho1i5jjLM3SK8yX+1VdbRjERa9zp+uARqZ6mGhqaFE2mMeVnxpnrPU1KutyAm+/tsowUbPkrEo+QjUe69YbQ7YKlM5VKhjqWR65u1DOwK/HCSPH7o/v/299lNlDX526XRyrKUHHcxd9RBaOa06dXab9q2UX7T0tHTtOqfq+TBhsMo+cuG0w+ke4nSc+QSHc15SVHQqd1GoGBqdcpkEE0DjU5qc8NyQqdOtB6/9Qig9yx9F2YcoVwA2VO88leMRvUbHEGcL5WqV6rt+uSDTPF4nHFnaoPnuq7QlPG1CFPa7mm/DKTpRyMEWlY7i6SdGeLR/q31CtFeeYUrU5O0uqpmWjZZSEpb+aoOkv+XPlKkp/rl80wgl1H340UT8X96dIK0S+9tjsjqDgcp4ib0yg67cejmit6qih0uNL+PsqJeNB5vn6ce6RDdGR9TPU4hbvofa5OBu7j/A5Af3wgHmB+Yvkdir5cEKMqeckXJ8dlmKGhcVqqXrS+b0iXO5q+PPTLf9GoRKbAtFwaObqbbIXjHvVFHoUkxGmBjfHqAtGJtgwE7z/MeGoNR9xp+rBNHeopv/gcpoYbSTktxXpwNJZp6fJ7t7GWHlvl7sKVP1c8wr+1Xim4jA4cCOtQLlx5U+8Seequ/ODhjPlz1YkU+QEQ3LBnz57rjz76qLpM53vf+x699KUvVVedI3/j9MjTJD+S6CX/8DW6546b6Ny9b1IOAOxwGjUaOr0/+zs2APqEy67cfvvt/R1J8cimvvI40ctED7/XiDQ4rU4+ogBgkJAfTJyAgQKDTV+NlDQaP//FfJ+ZCzK/kzIRaXBa0igCsAvgry/js7QADBp9NVJf/ttvE71wj7raBkRaMk0AAAADQV+N1De/9yOiF/xrdbUNiLRkmgAAAAaC/o6kHv0O0Y0vUlfbgEhLpgkAAGAg6KuRkvTis3MX25kWAACAjum/kQIAAAAc9N9I/cuz6mQb2M60AAAAdExfjdQbbt9D9MwP1dU2INKSaQIAABgI+mqkfvWlLyT68T+qq21ApCXTBAAAMBD0dyT1a7cS/Wgbv7YTack0AQAADAR9NVKV8dvoluf8hOjZp5VLDxFpcFqcJgAAgMGgr0bqlhfcGBiN764rlx4i0pBGUaQJAABgMOirkWLm3vkbdMtPnyT65+8rlx4g4uY0OC0AAACDQ9+NFI9s/mN1nOjvv9abT8Q5ThE3p4FRFAAADBZ9N1LM9KE76J7/4ZeJHv9qJkN1w+yj8kiF4xJxctycBgAAgMHCCyPF8FTcq1/+3MyGKhVloDhOTPMBAMBg4o2R4qm4B2YrdM+dryDa/FJn76g4rIiD4+I4Mc0HAACDiTdGimFjwtu7z73jtXTLkytyy/dcn6ezXxGGw3IcHBcMFAAADC437Nmz5/qjj2Z4v6Nw7UXfbXib99lPfbW1ey9vjsh7T/HWHno1c57S42WVeNWKH30n/B2U/GIQxgkAAAYCl125/fbb/TVSGjZWbKh4R13esDC+HxSvxcdLHfFKEvgdFAAADB4DbaQAAADsbJKMlFfvpAAAAAATGCkAAADeAiMFAADAW2CkAAAAeAuMFAAAAG+BkQIAAOAtMFIAAAC8BUYKAACAt8BIAQAA8BYYKQAAAN4CIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3FNr0EAAAAOgmXduZFwAAANgOsDMvAAAAr4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFhgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLTBSAAAAvAVGCgAAgLfASAEAAPCWwTBSjRoNDQ3Jo9ZQboPK5jkql8/Rprrccej87fR8AgC2hd4ZKcOwyKOwdWlQbXKVTq1s0dbKKVo9vU0NX7yR5euhMp0LHYRcQzVq+NYYSzkNvcvDQzkBACADPTFSm+fKNDRJtLglDIs6FqkumvUCbF6lVRqjfSVxXjpGjcYx4tOeU9pHY1fWaUNdbj64RHSAaD10EHId2E/D2ylTVg6cohVD91tb81T2UU4AAEihJ0aK2/NTK6JhVNdMeV5dR3r6ooev3UQv/1yt1fsPBl5itDJ+kq7QAk3qMHo0EB8xsHt8tKCvI/EbaYbhzRGSpkyVqVW6qtw31sfoxIkxWm05EFUPU8maRnCEg0czLZkfRUSGqC5aeVTuwuVcOTiXnQAdTvtNQ8er/qbqIq8cVh0CAEBndHX7eL39LzdoJ7j3Lq9MeIpMDrFoXtzkRm58/QRtzVylsmi8x5S7nCo8vZ9WuOfPDeQRoouR83101ohHNqLsfpHoiPbLyZnuZvxSjjpVtIxmGnytYPmO0EUSzqJRf5AOz4t0y1dpRjhsiEa+XhHxDTvSCPPgkDXmHupinkLZhoXbWWEcqTIv/AiZOW2Zznqo30atRqQ7AAzHbxpCyRQtruyn07l0wfIlyBHTlcxvvRKUpU5HxtPyl1R3AAC7m65tH88NjS0yE+6Bxxt8SdwYyAZVNLi6ATXd9bXtPN4AFnG3NeS6odawv7P7qMENL/+dHxajiLO0rzFDV+Vf4b+rMgXGR1gBujrToH1nhQGaEbqJyMBGbFKMLS3yMjp+Ha8mMV27LpLlECnHw/I0o44/ng4AADhw2ZWebR8/dmWJHuzl1M/GeqxRLYDtvY26FcLvpRbq1BDpjVX4bokOV4mubm7QOu2n4cBX1xnez+++GlRf5Xdeh6m6aspQpnkpb4XqcppNT8N1gEMXiXJIA7VEVf6ghcOsnOJXdgAA0FV6YqRmThGdHI82njwt1ZAfI5yks+oGf4xwZarSbhzSKFdoymUIYx87WI1ZTA43wXup06dXab+ySCIoLR05Tav8PipwSkam1ZI1lClBFyW2hKd1GoFhrNcpkEEYh5p8+cPGaoVOHWi9NytEgi4S5WAOVOmwUoJT1wAA0AE9MVKlYw1aObXa+thBHJPEDbBoWPkz8snAbfzkGC0GL0ZyIuJZHBOGUMWvp5xKx+iike6R9TFH7z4qhzwcHyDwaOIKtRrjwOEKjcnPDbMQlbUlU4Iu2BKKDFVVony5IEYz8pIvTo4rucdpqXqRjmUVxUqCLhLlOEYnxk7SuArj1jUAABSnJ++kth390r6QwQMAANBPtv2d1HbQMD71lh/JwUABAMCOY2CNVHm+/UU/AACAncXAGikAAAA7HxgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLTBSAAAAvAVGCgAAgLfASAEAAPAWGCkAAADe4v0Csz/48TNUX3mcvvy336Zvfu9H9OVHv6PuBLzh9j30qy99Ib3h126lyvhtdMsLblR3AAAADAIDucAsG6dj932RXvPe/0TH/vyv6f61G+jLP3kl0cgE0WglOMQ5u/E99iP9ijAc1ms2z9PExHnr1iBdhVeHV4vw1lL3zuoCOl+d5C8pju3SWxrbrVdNr/OfpPudTFp+d5s+PMNLI3X+0iPS4Nz/yNP0g196A1HpjUQv20f0r15C9AvPU74EfM5ufE/4Yb8chsNyHN0gUjm5sg5N0PnQoUE13hnXy0osZJts0hzvnLsyR80znj9kA9MQeKjX3d6IDnr+d3v5peCVkdKjp9lPf41+8PJxon/zWqLn3aTuZoD9ijAcluPoxqhq9PJaa6ffS0tEB4nWQodr1Dw4QsOlaVpens62U+92wbLRKO2VGxR6KF+cQZCRGTS9Av9BPUrEGyPFxuTuuTrd/9ATclQkR0hF4bAiDo6L4+zEUFWmmnRNdXE21kbp+PFRarYciKqHqKR7QurveWOvq3A6iO8pt6HxWbqsnCPuPCrTbrpnJe/rrfg36fxEcL55fiJMY6itFyZ6+zKNhdbuyG3yGWlpP3qUmDf9yOjSQVqc5v1E1ujshCVdGWeaPDzy1X5U2UTCGToJ9WT45fA2veow2k27x/OkryPxG2mG4R35MutNiNDfUeF+eVbukjzBASNxaT1HyVx+triU/K186zRa9SNE+c1W52pUU2Vba3Bc+pwDKT9hOCPNxPw78mb6cT6PZlhLvZMyW8pXn4fxiCPJXYdTf1PbDx1O3drpeGOkZj/1VfqbJ39GdNtvRKf0isJxiLg4To67KMMjREuXZI2kayRGTeUKjS5dkhWkUV+gUdmlNhAPy1pF7XO1OEULcjooaNxGF5X7yhwPyARR95W5Jk1yrSztDUdwPHobnSKqy8q6IR4VIYOosEdnR2lR7ae1ONoa7QXwlvAijYNztBJJTxDKx3twcfprdFzFs7VSpaWjQt609MVZaXo5CMPH4ijNntVPk4MMcWbicpNGLgTpimzRLMvryocKEsCNHu+OqfyIY77s0D9jLUeXXl3lm0CWcsgUb4mmL7RkWp7ecOfJIFv5OfSTtywz5ZX9qbJlfU8eJdLnlmeolS9b/tPqgkuvGWQT7sK7qncukuK3uRvkaj92B14YKX5/dP9/+7vMBur63O3ySEUZKo676Duq0qFqML+3eYmWaK94JIbFY8gPqDBazSmqxHdbFA/LjHYTFk5WJjktaLhrYu6c1sGFuqiS5XAEx6O3yswINbkVYP+jQgZuJGRvPuhNludzbPpoyiGnroxRgXgQLsvGJyV9Gdbo2U0ukBheJjy0TIY4s3CwSoeUZ6kvlteZDwNZfrEy4HBW/Qts5egiFk8mspRDkXiT8mSSpfycceUsyyx55Xu6bFnf5jnfy5yvhPg1sbhCssgmCOtdcNlOUvw2dxPzflr7sUvou5Hiqbg/XVoh+qXXdmcEFYfjFHFzGoWm/dgg8MOwsUaj0iKVSNRR8YDmHAHkRNRPYRsbVG+KNEqHqNo0ZRA9eu5RbVWoLh+o2BRLHkTll6OC8AgMXmL63MCNL1GVPx7I0bNLzlOHOPKxLYg8tE/D5WQ75S9YfiYdlWWv89pJ/N2QzVUfitaTbtSvAabvRoqn4n7w/Jfnegd1w+yj8siMiJvTKDbtF/Qaz5wRw31lkYTdoqWjZ6jJ76MCp2Tk9MgSyVlDAU+RyEon3WdJz7RI96mKfCi4tyYSVWkEhrFep0AG0cjU5KQ4G6sVmjvYem+Wi1j6JonpM0bPMsxPCqlx5iTUV0I+QrghpZifBP3nolyhKaN8Ixg9bqeeXPJLd0u9saHTyZqnLOWXEFfhsnTlNY20fDnyb0X6SX8eXUTStpWvqz4k1ZMkksLJEXEHndQBoK9Gikc2/ENdetl+5dJDRBqcVpHRFPcaL4smTj/UgcPl9vdRToQx4Xn/8WAa4ejaqOq5Bu84mpOB+zi/Z5pXj514YLjGV1WifLkgeq3yki9mx4MpiaFxWqpeoOmsokSIpi8P/UI2Mf1pOj4avKiO5ieFpDizIhoRne74UpVWpL4S8hESvLsw/dQaCfrPRbR85TQROws9XeB3Jyo9t55c8kfjdYbn8pgKpqkmzg+n5ylz+SXop3BZuvKaRpIs7vzb43fpNUE2W71zlm80/rA+ON3TKBpuZ9DXFSfu/9K6/BGu/JovB/p9VK7RFLP5JTr3v/463fPGbTCKYPfCP/atV2irkMEDOw5XfShaT3Zg/fJ2xQle6oheuEddbQMiLZkmAF2mYXw2PMQfEcJA7Wpc9aFoPdnN9auvI6m7Tz0QLHWU8zdRhUdS//x9esMvPkYPnLxbOQAAAOg3/o6keLHYG1+krrYBkVZ8gVoAAAD+0vev+3ry2bmL7UwLAABAx/TfSAEAAAAO+m+k/uVZdbINbGdaAAAAOqavRoo3LKRnfqiutgGRlkwTAADAQNBXI8U76tKP/1FdbQMiLZkmAACAgaC/I6lfu5XoR9v4tZ1IS6YJAABgIOirkaqM30a3POcnRM8+rVx6iEiD0+I0AQAADAZ9NVK3vODGwGh8d1259BCRhjSKIk0AAACDQV+NFDP3zt+gW376pFwNomeIuDkNTgsAAMDg0HcjxSOb/1gdJ/r7r/XmE3GOU8TNaWAUFYXXAcNf/MXf3fV30Ojr2n0mx+77It3/0BPd2z6eYQP1+FfpnjtfQefufZNyBAxXWN7UDQCwe/D1ufd27T4Tnop79cufK41KV0ZUykBxnF2f5ts8R+XyuQx74PhLTyrqk9+n8oe/P9B6SUTnr9f5fOQ7NHTimjxqjyi3QWMn5CGJtDrg6bNgfe556w9hvPioebh7ojdGiqfiHpityFEP7/vU0TsqDivi4Lg4zk6m+cqq8IJj5+yAufr/vLH1APEDdeJxOvekuqanqHbiO9Tw7UGTcgYNX+vwUM6OELr/5DN06k/20tafvJhWGz3Ol6m7runRyMPpvTR/h3L2iUGvMwXl53YsSoNqk6t0aiXYLt/HHUC8MVIMGxOelpt7x2vplidXiP7ha/k+T2e/IgyH5Tg4ro7fQx04RSui8LgAtxaJJgd8BKX52N8utra9/puniG4lWtdG6slnaPXW59Hwy19CjT96CeXZOLfn3PpiWhENHzd+wbGHyj7KWRTWPd1I+14uzrc7X91Kz8wD6A0Fy6ptJLV5VZTVGO3z+OHxykhppg/dQV//P3+X7rnjJrrl778cjKy+ezUYIZlTgXzObnxP+GG/HIbDchxdp1yhqSvrYeMu4am/cKRVpnPKgm2eKyu3BHdt8BxxmOQKlyG+Z+mtdFUZpY0nbqQT5Rtp9Qm1tf6TQq+vuZlKurem/p67vzWCCadw+J4e1fzZP9EV5Rxx59GOdtO9P3lfudMzdO7Dwfnm5x8P0xjK2lPU8aq/gZxGmqEcarSYV47IKDMJHoHqMEpHkfQNmUI5Db8cXurwKZrUYSJytvxLdzMfjL6OxJ+UH5HfT4n0vv1PNC7cy/d/J6YX7T9NbpNYHrQ8iXEpN43tXiQOsxy/Q7UPB+61R7j89DkHUn7CcDqdWL4/L+q9Lf44ph9nXTfDPktnlTxRmS1lps/DeMSR5K7Dqb/WMrGE+59Em9BCjKLGT4p8BFvvy3Yl0naomSN2E/fOyY0Xt382yUsjxehRFRscueX7yHW5YSGtLRM168EhztmN77Ef6bcboycHm+dO08KB/TSsroNCXqcTeqS1UqWlI4EBKR1rBG5yBDZGJ8+KohWFfeTkGC0q98UxNnjuOEJyhcsQn+C9hz5DS3/DRukZukpi1HTHzTT29aekv4b4O/aKmA7FA73+GjV6+b2baUFOQwUN0tjvKfc/eTEdkJ6j7iuHnqHJ+8Vo7eU30ti3n5VGnkdvY79OVJcP1LO0zjKIh+rIpRtpUY2SFl8R+I2gGpbwwTsRa+BCOcUIS8rxLJ1Q8W39yc209Ckhd5oc4qz0ltuCMHz83o108r8I+RMJDBxpXYhj/g6HHhirPm+medahHi069NlyTyCiB1d+bqRj72yl1/gf9QdLeeU2ieXhj26ks6lxBTJGyFKO0t8ztP+dwo1l+aTQvz631M9W2rF8v+VZd/whrjLIIJtwXzlEdLItTpOk+G3uBtYysYebF21CizLNr5yiA3q2qLGPzgqjNbYYtB0rp1ZpUr+kunKS1ivsPt9eVj3GWyOlYYNzzxv3S+PDO+puffL3Iwe78T320xPjJApnXPUsxpeqtNI41hpiy6Gy6oXwwb0SPdIyeySTC0SrV2mztE8MrNl/0Bspz4sCT4pDkydclvgE4//Hvyd6QoyYnnyKlsRDWxKN837RSG+w0XriZqrEB6LigZ7Rbi9/XvCgyGlBw10Tcy+9+mY68NdPCdlFvL8u4hc9Sh69VUSjuCoMovQvjGKJjYd4uCaV4SnfY2m8dOMXHjE/pjxy2skYlYiH9oo0TilyyLBGL/ST4p4YZbobGIHUY0wXTj0ITDm1Pl3E4slE3H+e/HRLbiZrXHHMexyHtRwFt95Mh+XUqJDFPOd7SWmbJMWvicUVkkU2gUw7HqdJUvxJemLM+ynPZk20CU647RAGa0Y9UKXDVTqwUA/0ZbhvN94bqb5jvpMyDZTGvC8PNiDCQI0vUVW9jNzi3or0LHou0k+F6tKIqKGzLQ7pX5MzXGp8RFtf+RyN8QP75LM09pqbhcuNdPg1JBru1miiFwy/gt99PUX1J/id181UfcKUQfTCpeG5meryoY+NkoogHlSbUUuUgxv0P3uKqurFf6aRSy8RcoVTS0XwLT9FcJRj1+gk/m7I5irjomXvCBcdSQ0GMFKdwCMcMdLimbw2DlTpsLJomw8uBRVGGK+afEHERmeFTh1YpauUEIcmT7gkmQyGhn5ZjiZON56h/bq3JxpunqpY5fdRgVMyctrsKXpQzcHz1JnMp3T/Jzqr5sal+6/fLB9c7lFSQ6cRGMb61ymQQTSmNX4/II3Vr9CpW4PRTmFicpgkysEYveAwX0mwoaNYWgl6yMUdN9OUoecIRu88Uc6k/MR7+N2Sm+lGXAnlmEha2jrfWeKXftLruotI2rYyc5VxUtkn4QiXOJKKtR2y3ZqqFCv3LgIj1RHBnO7qpJpa44NfPpaO0Ymx1jThkfWxoOcqKgGdHFd+x2mpepGOlRxxyPgVucJliE/AIyweTVwRBkE3XjxVwA9Q2/soJ8KY8PuNPwumOo48caPqoQfvJVY/GbiP83ume3ikJBAPNX2bqPrqIA02jAtiNBNM0wi3S98Kpk1OfIuWXrOHjmnZChGVQx76ZXSiHC+hE69ovftq5SuJ4D2HmVbtkQQ95CKq5/ClvZDzIr9nUek55UzKD9/79WC6qvxf9EdJ3ZKb6UZcCeWYSELaZr4//7wM8UfLwFXXI2GF8dI6H//6zbTCaTvLLBp/WMZO9zTs4ZJHUtG2Y5zfg3vwTbo3K06A7YUrIRsqMIDwD2VFo7dV2HAA73GVcdGyV+Ho2C97+dwPxIoTYJu59yGi+++WvSz8HbC/X/99or/+Tnb/+Dt4fz/5FG3Rv8vunvZXhZPP/YCBkRQAAIC+gpEUAACAgQRGatDwfDFIAADoJjBSvsC/rbJ8hRelsb2LQZoyZZIPAAC6C4yUL5SOUcP2Y2ETuZpEnxaDzCIfAAB0GRipFMrlGtXKenptk86F58oDjzDU9FvigowRf5ZFX/VIJRI2OIK0eE2+AotByuvkPNgXwxX+jvCSSsHvvcq1WiBfECAl3eDAdCQAoFNgpNK4skr7L27R1uIULUweIdLnp7nBDgxH+oKM2RZ9DQnDiiNMK/ihXaHFIBPzwIMky2K4Ysx07GIrvcbMfo5JkCXP0fgBAKAoMFJp6OWNhveLBts453tZF2TMuOhriBlWpxUnz2KQSXlgzJGRXgxX3Woja7ouuQEAIAcwUtuFaMDTFn3tC2ygrIvhAgBA/4GR6oSsCzJmXPQ1F91cDNK2GK7Gtm1I3nTlSE29uwIAgBzASHVE1gUZsy36mo8uLQbpWgyX4XtTwTRl+ey6cvRzEUoAwM4EyyIBAADoK1gWCQAAwEACIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFhgpzeZ5mpg4T5v6r3LuKr2M2wfS8rfT8w/ysdvqA+p/IXapkdqk8xNDNLQdFWaQKuZufYh2Ur6L5qVIuO0K0w92Up0YcHankdq8REs0Jf4t0SXUQrCTKE3T8vI0dlAGO4ZdaaQ2Ly0RVWeoMnqZlpKsFPem1MKrrR1ojR6WvK9X9+bRWXylb+F2dJYuX56VC7hOnF2Trpdsu9dG0pqg83GxVLrnI7v9WsJIfzWq8UhRxq9GjfKcAyk/YThDflNWjixNJsb0My7CK2d32DU6q+SJymz0Ws3rSDziyOUejT+iu5C0fMf9axpUC/0o3drCybQTyiPTfYtu1N8gTy7/7TJunp8Ir1vlUqTsi+gtFqbA8xCRX+czTValkzZd6XttYWNy1motnUr/xjOjn/lIPGbZO+pdoxam586TTe+7j11opDZJ2qhDJSpXpujy0qWgUrTBO9DO0qjegXauGexAW9pLo5fX5PYVbOxGp4jqsvZtiOZ3hIb5NKRE0xfm6ODBObmX1PLMCJGo+Gvm7rVnuFJyWmt0XO4zxXs6VWnpqG5oDMKwerdfR5jLTRq5INzkTrxHifR5mJYlX3FZpzcyyBSNa2tFhA/dU2QT7sI7zdryGZIUf950Td2Z2PJt048JN06TRDp9ccyXozJFwiWWR4b7Lqx1SWOTkQday+H11uIozapdmPOXfRG9dfg8iIb76OyoyFLgvjjKz2FCmZvkeu5ics5XUp75pLK31Ds2QLJolmmabHkCJrvPSMmpvioJG0XCStHUZceU3+Y1aopKGu5Ae6hKB+UOtGWqTDXpmgizsTZKFfGgNbnGsv/RvaJ6p2DEScMjQePKYSM793IvzlJZzbBJYQ6q/HH85jnfc+YrRhaZYnGFZJFNINO25VOTFH/udC3+bcTitupH1qFYfEnhksqDSbvvwsxT3L9NRsbs8fMuzM1r7Q16kh5dZNGbDVseXOlzB1G6B6OS8rxo+LPKmicd6ckk5ZlPyruZLiOM1rg0jMpo2fIk3adpmY2YelZ2M7vOSHFPSA/jh4YmRfVImfKzIOo4rW00qN4UvajSIao2RYXcWKPRilkbcyIqM/faZI9OHvEev4UiYfLQSfzdkE3oNJw+NHG5M73WySDDBiqyC7MYLahbbfRbj9b0yzQvzytUl8+vmkLbhnratWdepLcYGWU68gRCdp2RurR0maaMKRAe+lun/OS03mxrB1o2bmoHWu4p0Zkz1KweEiOnEvFlvU40Ep3ra5HWC42llYkiYZiEfEm0rFnil35aI1EZF59klC2StqGjMB7XSNflXlQnjCPfbfphuJGiWDpZwhXFpps0bDIyxki2La48Za/JozeNkR8rrvSFka3JlzTcsK/Q3EExuqEcssZJy6chZ+Izn7Psh6eXaZEmw/d4bXniSznixTspZtcZqbYpEN3gtT01vAPtHDX1DrQ8b6x3oBWVkp9ufq+lLxdED0s//BHEsP242t1WvyhuJ5qWPPQLVCdFwjBJ+TJkPT+cIX4RF7/XGA/uH10bVT3zBNnEwxyMYkXaS1VaCV6U0AXuXSr3SDxG/HI6Js29iE4S8h3RT0jwzsJMp9aIpm0PVwCnbtKwyLgh8jna0n8krtxlL8itN4EZJu/zwA/a7LhyG6el6gWaLhUsc0lC2EjehEviM5+/7MvzizQq8jJxSVy05SnwAwKwMy8YHPiLqHqFtuINgMsdADAQYGdeMLA0jM+Gh/iLKGWIXO4AgJ0FRlIAAAD6CkZSAAAABhIYKQAAAN4CIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC34Me8BXnLW96izrLz+c9/Xp0BAADQJP2YF0aqIGykHnroIXWVzp133gkjBQAAFrDiBBgseJuCzCtZ9wgfZOgGefKxU/LsYqfnb4cCI9VDvvWtb9Fb3/pWunSJ1+OPEu6Oqo62nba7Ra8fTDz4oBegXgEFjFSPYAN177330vDwMP3Wb/2WcjUwdwRVe9H0xFCVpml5eZqwRQ0AYBCBkeoBpoE6c+YM3XTTTeqOAzYkbKjOqJ4j9yLDUZbaTlr2LGtUm9Ajr006H56zB/YyocLwoXb11D1S9fe8scVFm1FM8hORSe8YKmQ4Ohtuxz9Rq7V6v9K/3gqbZTXyEcZj5k2nG9s+m/eKUulF8qfTSaDNv0onDBe5blBN+xVHTQ1+LyXpS2DVedzdIqsrXIgpm9RZF3XZYD+tusRHPG9u+WJ64nAROdx58bVeAb+BkeoAnsbj6Tw2SprcBkpT4i2oebtq0QiMz9Ko2uJ+hXdl1U/05SaNXAi2vF+YPEqkz5VxK00vG9vij9JsfF9s8dCvVfT9VrgIVj8s0xod13GvVGnpKLsHu78eVKPC5fmKyoNoHy4t0egUUV2KsEFrNELDiXnT6c5TuDMUNzK8V9TWMk3TeTrKO54qGRZHU7YgF2Gz++fGTiYU5E8c84eEcwZ9WXWeIe3UsgrrQw90yVue67ok0+f6FG3E7fJZ9FR21Y0YvtYrTDF4D4xUB/A0HhsjNkpsnAobKJPNa9QUD6fe4r50qEoHF+pBA3KwGmxXPTwiHmDjnO8x/PDp3uTkAlHzWrSxMOKNhDOx+WGZKNhKW8bN27WrRiNKmSpTTbomEt1YG6XKzAg1uTXh8KN7qZSYt9i2/qJxGZcNmGpcuNGWMgSNaXneaHRs5PG/eYmWKJY+k0VfNp1nSTutrHqpS0bXH6ZcoSlRwtfMArXJZ9NT1rph02XWsL3WBfAaGKkOYCPExkgbqo4MlHzQuFdYEG5UxpeouqJ7paInqm51BfGwh+/Q5GF/yEX7Q2sbDao3RV5Kh6jaFI3FxhqNVnI2CSK9RbNHLFKbl+lWqC4btdj0TRt5/RfAqfOUtDOWVe90mULeupSxbljpe70CvgMj1SGmoSo+glLTFcenqSSneWZJz/7w9MblqUq2h97oHctwwWnnxGRqw+j9ci9WKIGa1UNUEv/4sl4nGmHrmzNvw9PLtEiTNMEvDkTDWZMvENgArNDcwaBnLW4Qv5uTfkxs/llIQ9ZQR9zoUUL+krDp3CmrQYay6pku4zTqtMDymD0km3w2PaXVjSR8qFfAe2CkugAbpY9+9KPyyGygxEPFL4XlNMfQGRoRvdZ5+VSJho0/opgM7o3zu43gRjKlaTo+2orz6NpoF0dSUZnkoV9kc7pTwZSNfOhFg8EtWlW1cHy5IHq/wWX+vJXnF2l0dpwm+EMG8TdIf5yWqhfU+4QNWrt8MEwvhBOO+y9P0wXuRUs3U0fBOxAzf/rDiURcOrelbYqXtax6pcuza9H6x+9nzC9AnfJZ9NRIqBupeFCvYKi8BytOFAQrTngCf6VVr9BWFkMOAng6j7+7wU8TgCdgWaQe0Onafdzjc8Fz8yAb/Kn02b3LahQKMgEjBTwDRgoAAIC3JBkpvJMCAADgLTBSAAAAvAVGCgAAgLfASAEAAPAWGCkAAADeAiMFAADAW2CkAAAAeAuMFAAAAG/Bj3kL0umKEwAAAAKw4kQPwNp9AADQHbDiBBgceF25zKto9wgfZEjCd/m6zaDkd7eVyzYBI9VDeKde3l6et5mPE+56Kg/HhnydVPrteGDwUIJBBXV3YICR6hHmVvK8zXwb5o6ki0STtgemNE3LWKkaALCLgZHqAaaByrRTb7lCU7wLqerdna+p0ZXu7fHfyGirQTV1zVtVtEZkExTs4bZJ54/O0mW1sZ3c2E3GEfdnEEk7OMIdtq1hY2nUaq2eaURe3jlXnUfiMdzMPLObhveKUulF8qnTSaDNv0onDBe5Zn0qv+LQGx5esunCwK77FFllujWqTeh4g52Fg3PpQV630mPZLOUlsMrn1HFSmspPGM6enjtuR/mpezIqGVbf706dCIn4D47kfIn0t7Hugs6AkeoAnsbj6Tw2SprcBkqwef4MLRwcIbl7t3hw1io8wpqncIsktUtpXT8FvN232h67NL0cjMbkiGyUZuUe2sEOqgfVaG15eoNq42t0XPtbqdLS0VjjyYRpc1xTtHCG/fDW9rawsTTmKzSqtvvm7btHp0jJu0FrxHlTW+QvBvGs8A65uiWx5ZkbAN4xdmuZpuk8HeXdVpUMi6OtbcWtiLDZ/XNDJBMK8ieO+UPC2aqLKFbdZ0n7cpNGLqh4J3ljJzMNodfj4lwXtizr49GdfRlnWbl0nJSmq4xNcpYfU+Jt3XtUJzLro891F9MgHQMj1QE8jcfGiI0SG6dcBkpUbr099/hSlVb0tJ54cGYiT3pAudJquBr1Js1pT/xA6B7e5AJR81qscRFsXqMmBVtxS3/igbusHsoIZtrDI8GW4VnDike0MtWkayLxjbVRqsyMUJPl5fCje6nEf434S4eqdHChLh5/QTzPrBvZuKgHnxs7KUPQWy3PxxrDOHn8b16iJbLo3KaLODbdZ0n7YDXY9pzjNc/lTQGPrJVuGvUFmqpYpHeVlVPHCWlmKeM85RfSwzoRx/SfJ1+SbZQT5AZGqgPYCLEx0oYq1whKVO7wnVSW907lGZpr8oPRoHpTNTLcSI4vUXVFxbMieoeB73bM9OSR4yHKGFa0DbS2wfKJ3mfpEFVZ3o01GrU1skmI9BbN3qpIbV6mW6G6bHBiUytt5PVfAKfuu5E2N5o8cha6XJiivOorRCf1I4He1YmM9L3ugk6BkeoQ01BlNlCFKNGhapPqtTo1q4daRk33igU8VXE5OA3QvUY57TJLciYwL2lhjZ4p9zCFApR8LC9RvU40wvOYsXikrGrK0sbw9DIt0mT4Pq0mJ/fZAKzQ3MGg1ytuyHcr0o+JzT8Lacga6oobJCqoG5vunbLmozwzR83JSWrOzTh11EZOHYdkqR8F4+5ZnchCWr62o+6CjoGR6gJslD760Y/KozcGKoAfpOYC0XE90c3vqkZb04ZH10ZbIyn1HounOibOD9O86Ok3JwN/8tAvilMRja0rbCQN4SIeZm6pq6rl5ssF0TMNLqPxjPN7m/nkJq48v0ijs+M0wR8yiL9B+uO0VL2g5vo3aO3ywTC9EE447r88TRe4hyvdTF0F7yfM/OkPJxJx6d6Wdky8TLDxPGjJWyL5dRyQUMYhBePuVZ3IZAAS8rVddReGqmOw4kRBsOKEB/AXVPUKbWVqiAcMztuZkda7SgB2MFgWqQd0unYf98hs8Lw5yAZ/6n127zLtTBs1RPXK1o7MGwBxYKQAAAB4S5KRwjspAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLTBSAAAAvAVGCgAAgLfASAEAAPAW/Ji3IJ2uOAEAACAAP+btEbx2X9ajI+Qun8Hilj3dAYC3n8i88GwXcaXbL3k6xQe5+ynDoJbbTqKXZbDN5Qsj1SfatqJ20qDaZJPm1L5Fu3Ittx30wIEBZVDrSbfk7mP+YaR6CO/Uy9vL8zbzcZZX9PbVKZvLyd1FR2nvbl4KuzRNy1gNHID87IBnB0aqR5hbyfM284moXsr5mh5d6Wk9MYriLa/1Ftjck2G/8VFYJLxwk9c1qk3ouILNAVvxcpAJFQcfE5S47U2WNKVHRSz9MF0VJkwqcr1GZ0P/MXki/oROQlli058RmWL3+V4YTscv9HKUtxQP9oWaqNVa6Uj/Ol+sPyPfYTwZdCGnaoP0IjoP8+Omzb9KJwwXuY7pRfWLLtl0YeCqB4mymulKfVj0JLCmLf1rd5Weis9abhEsZR+JzyyPhPofux91t+k3Vk+CwkzJRyBLWplb9W+Jx5peHNOPbDeUG6ebK864nmP5P7um/AV6bZUVh3PI1gEwUj3ANFCZd+oVFWCtora4XpyihTNcoYPN1oIRl3Bf3ktnReUbXQz8rZjbVIfh1cjscpNGLqi4Jo8S6XMZL3ewloO0ZHqjNOvcvlRUvKxpmuj0ZfwsQ6vxsmL4F1mm2aPtD3TwUEwSKVn4aJv+tOqR87BGx1WYrZUqLcn4gw0PtX6X5ys0qnZr5d1XR6eI6lLoDWFCR2g4ry64EZDiLtM0naejvFmekmFxtLUrrBURNrt/i14OCWerLqJY60Fa2iXeqTZJT4Jc5eDyb2Ir+6TySK7/+epnrJ5Mb2TIh6gHGcrQ+RxG6lOC3kKiutjidkPdCckUp03PsfzPjKgIhftxobug8IUIdVqYOl5sk88EYKQ6gKfxeDqPjZKmkIFiRAWY0a3b8Eh7BWN46s/wxzv1HlyoBw+XGZ7RW5tzXOa5vCkwe1GTC0TNa7FKr8iTpomxtTqVKzRFagt3F4Z/mYaxtXfI5iVaooQ0GZse5ZSpGo3yIR7my7b4xaNbmQq2e99YG6WKeBib/ABy+NG9VMqjC9EgjMtGQBktbtilDEFjWJ43jJmNPP5derHpIo6tHqSmnaIn9pK3HNJkteUxsTxS6n/e+mmSNR9ZytD1HJrxJKWnienCSpY4szxjJqw7pfNGfYGmKlkDZgdGqgN4Go+NERslNk6FDdR2ww/G+BJV1ccY1l7XTkM8oHI0Gh72Rl+0Y7S20aB6U4wIeAv3pngAN9ZoNO/DJ9JbNHv2IrV5mW6F6rJhSOq5M3n9F8BZD9LTLqynjOXgPZnykaLHPM9hL/TWlTi5w7IgRtKiLixMUQ9sFIxUJ7ARYmOkDVXPDZScZpklPSPAUy2XpyrFKqvRk5TxBKftdCNNngbg9HgeyOgButJ1psGNIbVkyUwsD20YMnFvXBQgNauHxIigRHxZrxONsOw5dTE8vUyLNBm+w6jJyXpuuFZo7mAwEhE35Ly+9GNi889C2vRXVC+MrR44ZW2RqCcXaeWQhC2P3XoestZPfS9rPjLoMdNzmCU96WeJLqn4nXFpXHEm1SVDNyblmTlqTk5Sc24mv+4zACPVIaahymOgJuTwml9E5ukhi8ouelvNSe6VDdE4z3cX+Sa9NE3HR4OXoBzP0bXRhJFUwTRl3oIwQzzFzV8YiXQv8OjClq7hf3ypSivWNIK5cS0LH+FAJZFoHuShX2KzLkRPkGWShkI8vPx0V1XLwZcLYrQQXObXRXl+kUZnx2mCP2QQf4P0x2mpekHN3W/Q2uWDYXohnHDcf9mlP4te2j8obcdVD2xpx8RL1pOLhHJIxVb2HTwPeetnpJ4MZ8tHmh5d+m8ji96EH36nNZ4Wl8YVp+MZM/MffjihYMN20FKHuwRWnCgIrziR50e6d9555+5ZcYKnMfhdNT4bT4e//qtXaKtIZwMUA/Wzu3AdPjNCKx3oEytOeEjYe1EH2J1sXmv25GUzANuF/GDieO8MPkZSBcHafQAA0B2SRlIwUgAAAPoKpvtAd+E5/cwvvPuA7/LtJKDrdorqJL6QdK8Wlh6wMoOR2u0MUoVlWdVD2zqiS8n0LR+DoMd+yLiTy8URN3/+TfLT/Dw0YgtJx6+Vt10IjBQYLNp+gLjc9WVYQBcp9XmB0z6kv7HW+jQ/M3IFCGMh6fj1LgZGqm+InpIxIpDDee6ZhW7q91Oqt9a2+KbLnYnEk2PhSPboCmu682+8lHOESFhD/shvwVgG8572Hx0RRRbCTCWWD/U7jmILnIo0I9cZwsfTD5WmiIQx8p6QT9fCryGdytjjxXRDlP/oAqfBEcprkL7garGwbQusymvLIrMM3wvjceXbVea88oI2LhmfcfYnnym1TNHERPA7yvBayR+GM3TscjdwLXKb/nyYeXfoahuAkeoT+RbLdCy+aXXneAouHOlcODMqm335Fof86keAeg3KYBFKXhXAJacgzJdlmRbVKOiHxfwBYmQBzFy6CeKNpJkrfFyPZvfXoRcmIZ+ZFgDuRMZeLqbr6v1b5Y2SvuBqgbCauNzWRWaz5ttR5mH9tj1vrriDH9bquLaWl42tfPiaF5Z2PZeO+qwR5WJd5Naqz6S851wwuovASPWJfItlGn4ji2Ra3DtZONIZNiqblQT5yxVRqZWVatSbNMeeXGmxp6S0xD354OrDNZWTRzd8L55m3vAuEvSSmE+zR+taALgjGXu4mK4Lm7xxXPnuJKwmLrexJFG4yGyjYHkpwkVW8y6Im4SrTLOUdWmvfZFbmz4Ty9yiq7YK2RtgpHYioqJFGvK0xsOkk7AuyjM0xwuQin/1plHZe5FWGp2muR0yc2PbyQLAGWUUbVOPFtMtSCf57lRnXWGTrjUPJq9fWBRXmaaWtRilSfceLlTcY2Ck+kTPFsuMxROSZeFIZ1h2T1m8MlF+XoC0SfVaXS1Iyk6OtDohbVTTaZpp4W3pJ+olgSwLj9rIISP3lHuymG4nFM0300lYvchsOWd5mWUuR09Khm4uiOsq07SyZoTxti5UbCOrfFpXnE85eu2t4YOR6hM8nx1dxDG64GPhxWO5MhrxyMN4b5O4cKRz4UwRZ+rilcnyc4PYXCA6Hr6wcMmZgniIIu+k9MvipAUwQwqmGZIQPqJHM8ZkvVjhuDIvABwnh4yiUeKWvOuL6RY1VJ3ku0hYsy7pRWbz5DumT27UW5+e2563AnVB4irThLLWcKHGF7l1jvQS5LPqanvAihMAgN0HjwC6vMhsozZE9coO/E1TD3QVBytOAABAT+ndpn+7HYykAAAA9BWMpAAAAAwkMFIAAAC8BUYKAACAt8BIAQAA8BYYKQAAAN4CIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFhgpAAAA3lJoFXQAAACgm7hWQc9tpAAAAIDtAFt1AAAA8BoYKQAAAN4CIwUAAMBbYKQAAAB4C4wUAAAAb4GRAgAA4C0wUgAAALwFRgoAAIC3wEgBAADwFhgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLTBSAAAAvAX7Se0wPv/5z6szAMBb3vIWdZYdPEPpFNFrEbDp4Q6EH7A777xTXQGwe3nooYcKGyk8Q26K6rUI2PQQAACA18BIgdw0Gg2amZmhP/iDP5AHn1+5ckXdBQCA7gEjBTKzvr5O73vf++jTn/40/T3tof9+6zvp/ZPP0L6XPUX33XefvMd+AACgW8BIgVR4pPSHf/iHdObMGXrsH39Kj+z5n+mhX/7f6LsvuJ1+c9/P6PS/f5ree/dPiH7ybemH/XIYAADoFBgpkMrTTz9Nf/uiN9KVX/l9+tKr3kv/8MJ/S3T9OtHP+a74K87Lr36WPjH9FJ2+58f0uwd/KMP0jC/M0m233SaP2S8oN0D02Mfp7W//OD2mLttIuw92DjuorGGkQCY2XvLb9E83vVLapLiBkvBfcbzmV35G77xLjKriGIZFHoWtyxdodmqN3v/Fx+nxL76f1v6vHdToDnrDAiPopmv1f/cBIwWyIY2Q+qsNlPzLp4GBajtXPPbxt9NtU0QLjwvDoo4FWhbmpgCPfYPWaIReJewlvfLd9Bd/8W7iU+ABKA8rXa3/uxAYKZCJF//zNwLjYxoobZC0UVLnX//Wc4NrxV8+QGLkM0dvVtfMm+fUNfe+wx7mbPDgqh75x2dbPc+g4ylGUW/6AD1M99OUDqN77pF4lHu8Z6+vI/EbaYbh304fjw8HsoaR/mZp9u2B++wXHqOPh+ccSPkJw6m4hJQf/2ORt4c/QG8S7m/nyNJkYkw/UjcKZ9irdFHJE5XZoid9HsYjjiR3HU79bS8/Rzh1a2fyWGL9lwYs1Ee0PKz642cg9K/cIzp11JMBBkYKZOK5P/uJxUCpv4wyUMyPf3KD/Kt54GE18mkjMDojC0Hv8ovvX6Mp/TSKxvrqhOp5LtxD98tpvTfT3BffT6973fvpi+zO59JzNJ6WewJh/NxYcPir9B84rAx/Nz3wx5bGM2uYh9do34eEG8s99cdE+lzmwZXnV9K7P9TK21+8+xsZZHLlO4Nswl14pw/Y8hmSFH+Kvq3llyHcTuOxv0yo/zz4/ItAF1JPI/SBi0n1nzs8ckgWhpl7c0JZ7xBgpEAqt9xyC/3vL/sE/fzf/RH9/HfF8b/oo0bP+dSH6Tl//iFx8F9xfPLDdO+Dr5dhQl63j16lTiPw1J1olI+oLuYrf/tuet39ahrEcKdX7UtuzGLxZML0L6cQjdGZaEgffvgqibFjlKxhXnc3/TY3Siy3ec73kvJskkUmV76zyCaQadvyqUmK3+ZuYt535H3X4Kr/jDkKmrqfaO0bgYGx6k8YPIrpL6msdwgwUiCVV7/61bT8N8+lzSdUdTFGTfRzPtduRDc/+x36pZ98TYbRjDz8AP1lL7t237jamuYqimgU5OgsPKLTM1aKhMlDJ/F3QzaXXovquxvlNGi88lXu+s8G6k0P0N38ERCXUdGRZa/rYZ+BkQKpvOtd76LnP//59Gf/3y9GDZQyTObfV//w/5V+OYzmCE8rvUm/ewn4wqy4lg/wB0jPcDz2lw/Qw/dM5H/A3jxB97gaAqNXKeNX5xFicmSiSBgmLc9a3izxSz+tfIf5yyhbJG2bnlx6TdJ3EkXDDTRvdtd/PjFGts76qXnlb9PdFCvXovVwgICRApmYmpqib3z3F+hDD9wUOGhjZRiosR/+Z3rRvzwp/ZrwvLt896KnJMQxRdw4Bu+Y1qYCtzd9YIQW5or0AUU8PJ//JmPKg51f+W76kJHuH18dcfRUo3LII/WFfpEwTEKehbz/4Z5g6ubtH39Vhvij+W7lL0E20aDxhxns9qYH7qYvctpOPUXjD/XqdE+jaLjBxln/ubxHWuXhrp+a4L2lWa6zX0go6x0CVkHfYfRyBWden+9jH/sY/eben9J73/pjesGN1+U7qF/4+dNiBPWf6RU/XZdr+R04cECF6BP8m5TlCXq8kMEDTlx6LarvHpcTVkHvDVgFHXgLGx82Qv/12vPp2CdeRF//5nPpxT99jO76x48VNlBh7y925OULxue68jcpMFBdwaXXovrejeUU5tdygHQwktphbEcv8Pvf/z594AMfCJc+uummm+j9738/veQlL5HXAPgARlK9ASMp4D1sjM6ePUtveMMb5MHnMFAAgF4AIwUKw1/wmV/xAQBAt8F03w6DpyoAAAFFp/tAMts53QcjBQAAwEvwTgoAAIDXwEgBAADwFhgpAAAA3gIjBQAAwFtgpAAAAHgLjBQAAABvgZECAADgLTBSAAAAvAVGCgAAgLfASAEAAPAWGCkAAADeAiMFAADAW+QCs+ocAAAA8Aii/x+LYiEbPlKe5gAAAABJRU5ErkJggg==" /></li>
<li>Then you will see something like this:<br /><br /><img src="data:image/png;base64,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AgDgutL/it86dkORbhrer6riGA2UZv6vNwAA4NMH1d2QkXm1em3pEyRdKlXGMfQoAQCAa+VCepQ0E8Vf/vKXv/zlL3/5e5X+nnuPEgAAwIcu2KMEAACAwPcoAQAAgEAJAAAgiEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAggEAJAAAgYOXGjRtn7j0AAAASIv8PwvDyyx13qgMAAAAASUVORK5CYII=" /><br /><br />This means your test box is ready.</li>
</ol>
<h2>
Setting Up the Dev Box</h2>
To use the fancy new remote app testing feature, you just need to:<br />
<ol>
<li>Install VS2015.</li>
<li>Install the Windows SDK from the same build installed on your test machine.</li>
</ol>
<br />
<h2>
Workflow</h2>
<div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<ol>
<li>Dev Box: Write a test app to test the ABI functionality of the ABI.</li>
<li>Dev Box: Build the app in VS2015 for the architecture of the test machine.</li>
<li>Test Box: Run the "Remote debugger" desktop app</li>
<li>Dev Box: Hit the down arrow for start debugging, and select "Remote machine." If it is the first time you have done this, it will have a dialog to select your test machine. Select it and hit play. If you don't see your test machine, see #3.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPW6CaBqu6D6ksqo2y7LfORKcg4iBWAKKzVgbnQMlCiWlF9Oh9Hlh2PLICHseRAPVP1LTEvDQBz56-mMKcx71GD_s6V9fAb9cczdTYVffxqu960TC2BrQF9JSo95RUPtz0m62zhx53aCM/s1600/remote+machine.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPW6CaBqu6D6ksqo2y7LfORKcg4iBWAKKzVgbnQMlCiWlF9Oh9Hlh2PLICHseRAPVP1LTEvDQBz56-mMKcx71GD_s6V9fAb9cczdTYVffxqu960TC2BrQF9JSo95RUPtz0m62zhx53aCM/s640/remote+machine.png" width="640" /></a></li>
<li>Test: Validate that your test app is running and working.</li>
<li>Dev: Hit the stop button.<br /><br />Why did we bother to start the app to just stop it without any debugging? It is mainly to just get the app deployed to the test machine.</li>
<li>Test: find the name of the app package for your test app.<br /><br />plmdebug /query<br /><br />The output should look something like this:<br />Package full name: 02985851.Mint.comPersonalFinance_1.2.0.2529_x86__xm34sne40gbwr<br />Package state: Unknown
<br />Package full name: 1ED5AEA5.AngryBirdsSpace_1.6.1.0_x86__p2gbknwb5d8r2<br />Package state: Unknown<br /><br />In case you were wondering PLM stands for the Process Lifetime Manager.</li>
<li>Test: Then you run:<br /><br />plmdebug /enabledebug [package full name here] <appid> "c:\debuggers\windbg.exe"<br /><br />This will set the correct image execution options so that windbg will attach to the app container before the app starts running. Whenever your app starts, you will get windbg window to pop. This works for everything: foreground apps, background tasks, app activation contracts, etc.</appid></li>
<li><appid>Test: Once, windbg launches, set your break points in your code as you would with a normal Win32 code, and let the debugger go. </appid></li>
<li><appid>Test: Run through your test app that executes the code you are interested in.</appid></li>
</ol>
</div>
<br />
<br />
<br />samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-91142153678251783042015-08-14T14:04:00.003-07:002015-08-14T14:05:07.211-07:00How Can you Find Who is Using What Device Programmatically in Windows?Well, that is not an easy question to answer. The short answer is that there is no API to do what you are asking. In fact the OS isn't really designed to allow that, so some of the information required to figure it out 100% is not preserved in the kernel's object manager. In other words, you can't, not 100% anyway. Even Mark Russinovich could figure out how to make a sysinternal tool to answer the question. With that said, it is possible to figure out quite a lot about who is using what.<br />
<br />
First off, people use devices by opening a handle to them using CreateFile. You typically pass in a device interface path that you discovered using SetupAPI, or one of the other APIs Windows has. The IO Manager will resolve the device directly, or it also has other branch points where it can involve drivers on the stack to resolve the device. Ultimately the client gets a handle to the device. I will leave it at that. The important thing to know is that devices that are being used have handles backed by objects that the kernel's object manager tracks.<br />
<br />
Devices being used will have open handles, so you can look at the handles; however, they don't always tell you enough information of what they are for. With experience, you can recognize some types of handles, and even figure out what interfaces the match to. Still, some other handles to device, will not have that information: they can be symlinked, they could just be a named object created directly by the device driver (assuming the set the right permissions, etc.), or a lot of other reasons.<br />
<br />
Next, are we talking about user mode or kernel mode? Drivers in KM can open handles to other devices and they will not be directly visible to a UM process. You will not be able to see a lot of the references, unless you are discovering them in KM. If you are talking about a UM tool, then the tool could open other processes in UM and enumerate their handles, assuming it has enough permissions. It would probably need TCB (trusted computing base) to open them all. The UM tool will not have visibility into the KM handles.<br />
<br />
Do you think you could write such a tool? It would be a great way to learn how IOMGR works, and PnP. I could write one, but it still would not be 100% complete.<br />
<br />
A good starting place to learn about this is another tool called KD (the Kenrel Debugger). Dump all of the handles in the system, and go spelunking. That will give you a lot of experience you would need to write the tool I was talking about.<br />
<br />
-Samsamhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-38261476397093445442015-08-14T13:09:00.001-07:002015-08-14T13:09:03.201-07:00How to Capture Control Events (eg. Ctrl-C) in a C/C++ Windows Console AppI was recently working on a tool of mine that implements a RPC client for my RPC server. I wanted to let the win32 console app run until the user hits ctrl-c or ctrl-break. I guess you can also do something like getchar, but I didn't want to. Also, I could just let the user hit ctrl-c and it would kill the app. I do use RPC handle rundowns to clean up the RPC server state; however, I wanted to clean up and exit "safely" within the app.<br />
<div>
<br /></div>
<div>
So, without further ado, here is the code for using <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms686016(v=vs.85).aspx">SetConsoleCtrlHandler</a> in Windows for handling console control signals. <br />
<br />
There are a few caveats you need to think about though when implementing control handlers. For some events, there may be other handlers already registered, so your's may not get called. This happens, for instance, when using a debugger. Processes with a window message pump will also get some events through the pump that are not synchronized the process signal handler.</div>
<div>
<br /></div>
<pre>
/*--</pre>
<pre> User mode only.
--*/
#include "precomp.h"
HANDLE g_hControlEvent = NULL;
///// ctl event handling
BOOL WINAPI ControlHandlerCallback(
_In_ DWORD dwCtrlType)
{
HRESULT hr = S_OK;
BOOL bControlEventHandled = FALSE;
wprintf(L"got event %i\n", dwCtrlType);
switch (dwCtrlType) {
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
if (!SetEvent(g_hControlEvent)) {
hr = HRESULT_FROM_WIN32(GetLastError());
NT_ASSERT(hr == S_OK);
}
if (S_OK == hr) {
bControlEventHandled = TRUE;
}
break;
CTRL_CLOSE_EVENT:
CTRL_LOGOFF_EVENT:
CTRL_SHUTDOWN_EVENT:
default:
break;
}
return bControlEventHandled;
} // ControlHandlerCallback
HRESULT RegisterControlHandler()
{
HRESULT hr = S_OK;
g_hControlEvent = NULL;
g_hControlEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!g_hControlEvent) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!SetConsoleCtrlHandler(ControlHandlerCallback, TRUE)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
wprintf(L"press ctrl+c to stop\n");
exit:
return hr;
} // RegisterControlHandler
HRESULT UnregisterControlHandler()
{
HRESULT hr = S_OK;
if (!SetConsoleCtrlHandler(ControlHandlerCallback, FALSE)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!CloseHandle(g_hControlEvent)) {
hr = HRESULT_FROM_WIN32(GetLastError());
}
g_hControlEvent = NULL;
exit:
return hr;
} // UnregisterControlHandler
HRESULT WaitForControlEvent()
{
HRESULT hr = S_OK;
if (!g_hControlEvent) {
// called before registring
hr = E_UNEXPECTED;
goto exit;
}
if (WAIT_OBJECT_0 != WaitForSingleObject(g_hControlEvent, INFINITE)) {
hr = E_FAIL;
goto exit;
}
exit:
return hr;
} // WaitForControlEvent
</pre>samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-53955276915797728032015-07-06T14:17:00.003-07:002015-07-06T15:03:13.796-07:00MIDL: [ptr] vs [ref] vs [unique] vs [optional]If you author IDL files for RPC, COM, or WRL, you will probably need to pass arrays. There are a few parameter attributes you can use for pointers, but it may be unclear which one to use. You may have seen [ptr], [ref], [unique], and maybe [optional]. Straight off, even though optional seems like a logical choice for emulating SAL's _opt, it is actually a red hearing. For some inexplicable reason, optional only applies to VARIANT structs <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa367132(v=vs.85).aspx">according to MSDN</a>.<br />
<br />
That leaves us with: ptr, ref, and unique.<br />
<br />
<ul>
<li><b>ptr </b>- aka "full pointer," is supposed to be most C-like. It can be NULL (like _opt). It can be used for double pointers, where the size is unknown. It is good for aliased pointers, like using one allocation for more than one pointer.<br /><br />The problem with with [ptr] is that it causes a lot more work for RPC to figure out what pointers own which buffers.<br /><br /><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa367149(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa367149(v=vs.85).aspx</a> </li>
<li><b>ref </b>- acts more like const in paramters. It may not be NULL. The buffers may not change, or be changed during the RPC call. Cannot be aliased. Ref is the default.<br /><br />It may be a good choice for in parameters that should not change or cannot be NULL.<br /><br /><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa367153(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa367153(v=vs.85).aspx</a></li>
<li><b>unique</b> - is like ptr, but the allocations for the pointers must be unique. This make it so that RPC can make a lot of safe assumptions about the buffers, and skip a lot of buffer checking.<br /><br /><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa367294(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa367294(v=vs.85).aspx</a></li>
</ul>
<div>
<br /></div>
<div>
In general, I would recommend using <b>ref </b>for <b>const </b>type <b>in </b>parameters, and <b>unique</b> for <b>opt </b>type in parameters. You should probably stay away from <b>ptr</b> pointers due to the RPC runtime overhead unless you have a good reason to use them. Also you may experiment with the MIDL compiler and see what SAL annotations are generated with which IDL attributes. There is a lot more nuance, so dive into the MSDN articles if you need more depth on the topic.</div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-64725156703971365852015-03-19T09:58:00.000-07:002015-03-19T09:58:17.442-07:00What Have I Been Working On the Past Year?Winodws 10. It is interesting to hear my boss' historical perspective. It is good inside info if you don't work at Microsoft.
<iframe src="https://channel9.msdn.com/Events/WinHEC/2015/Developing-for-the-Windows-10-Device-Platform/player" width="640" height="360" allowFullScreen frameBorder="0"></iframe>samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-3645238053053745282015-03-16T17:35:00.001-07:002015-03-16T17:37:23.370-07:00Making Changes to the Windows KernelWe all have to modify the Windows kernel from time to time...am I right? If you are like me, you don't have to do all that often, but when I do, I always seem to forget to do these small things.<br />
<br />
<b>The kernel you build must be signed or it will not load.</b> As a side note, also many core DLLs must be singed like cfgmgr32.dll for instance. They are checked by smss.exe early in boot, and will cause your system to bugcheck (with 0xc000021a aka STATUS_SYSTEM_PROCESS_TERMINATED) if they are not signed. Also, how is the build signed? If it is PRS signed build, you will need to install the test signing certificate to the target if you want to run a test signed kernel. Make sure these environment variables are set. <br />
<i>set NT_SIGNCODE=1</i><br />
<i>set NT_SIGNCODE_PH=1</i><br />
<br />
<b>Your kernel and HAL need to match.</b> This may also be case with other components like ACPI, etc. but these are less likely to cause you problems. You should just always build replace the kernel and the HAL together. <br />
<br />
The are found in c:\windows\system32\ and are called:<br />
<b>x86</b><br />
<i>ntkrpamp.exe</i><br />
<i>halmacpi.dll</i><br />
=or=<br />
<b>AMD64</b><br />
<i>ntkrnlmp.exe</i><br />
<i>hal.dll</i><br />
<br />
You can just clobber them, and reboot, but your system will probably just bugcheck. I would suggest replacing them with alternative names. Try the following:<br />
<i>reagentc /disable</i><br />
<i>bcdedit /bootdebug on</i><br />
<i>bcdedit /set BootStatusPolicy IgnoreAllFailures</i><br />
<i>bcdedit /set testsigning yes</i><br />
<i>bcdedit /set kernel mykernel.exe</i><br />
<i>bcdedit /set hal myhal.dll</i><br />
<br />
Likewise, you should <b>setup up a KD</b> on the target so you can see what bugchecks you are seeing. Ex:<br />
<ol></ol>
<i>bcdedit /debug on<br />bcdedit /dbgsettings 1394 channel:1</i><br />
<div>
<i><br /></i></div>
<div>
<b>But, what if you forgot one of these steps</b> and now your machine is in a bugcheck loop that you can't debug? You can add them temporarily by pressing F10 to while the Windows boot manager is running, and you can add them in as boot options.</div>
<div>
<a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff556253(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/hardware/ff556253(v=vs.85).aspx</a></div>
<div>
<br /></div>
<div>
<b>If you need to change the kernel and the PC will not boot.</b> You can simply change the kernel or HAL offline using WinPE. There are lots of ways to get into WinPE, so I won't describe them here.<br />
<br />
Handy tip: here is the command to see what drive is mounted as what in WinPE<br />
<i>wmic LOGICALDISK LIST BRIEF</i></div>
<div>
<br /></div>
<div>
Hopefully this was a handy refresher!</div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-40809586679471515872015-02-17T11:23:00.000-08:002015-02-19T15:26:28.651-08:00SAL to SAL2 Porting GuideI have written before that you should use <a href="https://msdn.microsoft.com/en-us/library/ms235402.aspx">SAL</a> in your Windows C/C++ code. It allows to you do neat things like use Microsoft's static analysis and kill lots of common bugs at compile time. Whereas C can be ambiguous how say a pointer parameter is used, SAL can make the intended use of parameters and struct members very crisp. A: if it is hard to figure out what SAL annotation defines your parameter's use in the function, you are probably doing it wrong. In general, you should make your functions use the parameters in straightforward ways. B: Likewise, there is always a correct set of SAL annotations for a parameter's behavior, so don't cop out and figure it out. If you are still confused, refer to A.<br />
<br />
Why port to SAL2? Because 2 > 1 obviously. SAL2 does add some new functionality. You should not be lazy and just use SAL2 in new code, and clean up old code to use SAL2 while you are in there working on it. Should you go back and fix old code to use SAL2? It is up to you. It has some new functionality, however, SAL1 will continue to work just fine.<br />
<br />
<h2>
Const Protection, Use It</h2>
This isn't SAL, just regular C. Use const protection. Parameters that should not be modified should be const protected. For instance: _In_ const char *p is more correct than _In_ char *p if the p buffer should not be modified. Please use const correctly for parameters and struct members.<br />
<br />
<a href="https://msdn.microsoft.com/en-us/library/hh916382.aspx">Here is a table for the basics of SAL2</a>.<br />
<br />
Here is my version with SAL to SAL2 notes.<br />
<h2>
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">Pointer Parameters</span></h2>
For
the annotations in the following table, when a pointer parameter is being
annotated, the analyzer reports an error if the pointer is null. This applies
to pointers and to any data item that's pointed to.<br />
<br />
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="border-collapse: collapse; border: none; mso-border-alt: solid #BBBBBB .75pt; mso-padding-alt: 0in 0in 0in 0in; mso-yfti-tbllook: 1184; width: 675px;">
<tbody>
<tr>
<td style="background: #EDEDED; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<b><span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">SAL 1<o:p></o:p></span></b></div>
</td>
<td style="background: #EDEDED; border-left: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<b><span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">SAL 2<o:p></o:p></span></b></div>
</td>
<td style="background: #EDEDED; border-left: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<b><span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">Description<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">__in<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">Annotates
input parameters that are scalars, structures, pointers to structures and the
like. Explicitly may be used on simple scalars. The parameter must be valid
in pre-state and will not be modified.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">__out<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">Annotates
output parameters that are scalars, structures, pointers to structures and
the like. Do not apply this to an object that cannot return a value—for
example, a scalar that's passed by value. The parameter does not have to be
valid in pre-state but must be valid in post-state.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">__inout<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">Annotates
a parameter that will be changed by the function. It must be valid in both
pre-state and post-state, but is assumed to have different values before and
after the call. Must apply to a modifiable value.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">__in_z<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_z_<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to a null-terminated string that's used as input. The string must be
valid in pre-state. <span style="background-color: yellow;">Variants of PSTR, which already have the correct
annotations, are preferred. <= This is a pet annoyance of mine, don't be the guy that does _In_z_ PCWSTR.</span><o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">__inout_z<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_z_<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to a null-terminated character array that will be modified. It must
be valid before and after the call, but the value is assumed to have changed.
The null terminator may be moved, but only the elements up to the original
null terminator may be accessed.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
__in_ecount(s)<br />
__in_bcount(s)</div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_reads_(s)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_reads_bytes_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array, which is read by the function. The array is of size <i>s</i> elements,
all of which must be valid.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
__in_ecount_z(s) </div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_reads_z_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array that is null-terminated and has a known size. The
elements up to the null terminator—or <i>s</i> if there is no null
terminator—must be valid in pre-state. If the size is known in bytes, scale <i>s</i> by
the element size.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_reads_or_z_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array that is null-terminated or has a known size, or both. The
elements up to the null terminator—or <i>s</i> if there is no null
terminator—must be valid in pre-state. If the size is known in bytes, scale <i>s</i> by
the element size. (Used for the strn family.)<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_(s)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_bytes_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array of <i>s</i> elements (resp. bytes) that will be
written by the function. The array elements do not have to be valid in
pre-state, and the number of elements that are valid in post-state is
unspecified. If there are annotations on the parameter type, they are applied
in post-state. For example, consider the following code.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">C++<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">typedef
_Null_terminated_ wchar_t *PWSTR;<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">void
MyStringCopy(_Out_writes_ (size) PWSTR p1,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _In_ size_t size,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _In_ PWSTR p2);<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">In
this example, the caller provides a buffer of <i>size</i> elements
for <i>p1</i>. MyStringCopy makes some of those elements
valid. More importantly, the _Null_terminated_ annotation onPWSTR means
that <i>p1</i> is null-terminated in post-state. In this way, the
number of valid elements is still well-defined, but a specific element count
is not required.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_z_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array of <i>s</i> elements. The elements do not have
to be valid in pre-state. In post-state, the elements up through the null
terminator—which must be present—must be valid. If the size is known in
bytes, scale <i>s</i> by the element size.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_(s)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_bytes_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array, which is both read and written to in the function. It is
of size <i>s</i> elements, and valid in pre-state and post-state.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_z_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array that is null-terminated and has a known size. The
elements up through the null terminator—which must be present—must be valid
in both pre-state and post-state. The value in the post-state is presumed to
be different from the value in the pre-state; this includes the location of
the null terminator. If the size is known in bytes, scale <i>s</i> by
the element size.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_to_(s,c)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_bytes_to_(s,c)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_all_(s)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_bytes_all_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array of <i>s</i> elements. The elements do not have
to be valid in pre-state. In post-state, the elements up to the <i>c</i>-th
element must be valid. If the size is known in bytes, scale <i>s</i> and <i>c</i> by
the element size or use the _bytes_ variant, which is defined as:<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">C++<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _Out_writes_to_(_Old_(s), _Old_(s))<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _Out_writes_bytes_to_(_Old_(s), _Old_(s))<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">In
other words, every element that exists in the buffer up to <i>s</i> in
the pre-state is valid in the post-state. For example:<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">C++<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">void
*memcpy(_Out_writes_bytes_all_(s) char *p1,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _In_reads_bytes_(s) char *p2,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _In_ int s);<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">void
* wordcpy(_Out_writes_all_(s) DWORD *p1, <o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _In_reads_(s) DWORD *p2,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _In_ int s);<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;" valign="top"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;" valign="top"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_to_(s,c)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_bytes_to_(s,c)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" valign="top" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array, which is both read and written by the function. It is of
size <i>s</i> elements, all of which must be valid in pre-state,
and <i>c</i> elements must be valid in post-state.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;" valign="top"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;" valign="top"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_all_(s)<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Inout_updates_bytes_all_(s)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" valign="top" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array, which is both read and written by the function of size <i>s</i> elements.
Defined as equivalent to:<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">C++<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _Inout_updates_to_(_Old_(s), _Old_(s))<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";"> _Inout_updates_bytes_to_(_Old_(s),
_Old_(s))<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">In
other words, every element that exists in the buffer up to <i>s</i> in
the pre-state is valid in the pre-state and post-state.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;" valign="top"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;" valign="top"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_reads_to_ptr_(p)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" valign="top" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array for which the expression <i>p</i> – _Curr_ (that
is, <i>p</i> minus _Curr_) is defined by the appropriate
language standard. The elements prior to <i>p</i> must be valid in
pre-state.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;" valign="top"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;" valign="top"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_In_reads_to_ptr_z_(p)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" valign="top" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to a null-terminated array for which the expression <i>p</i> – _Curr_ (that
is, <i>p</i> minus_Curr_) is defined by the appropriate language
standard. The elements prior to <i>p</i> must be valid in
pre-state.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;" valign="top"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;" valign="top"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_to_ptr_(p)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" valign="top" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to an array for which the expression <i>p</i> – _Curr_ (that
is, <i>p</i> minus _Curr_) is defined by the appropriate
language standard. The elements prior to <i>p</i> do not have to be
valid in pre-state and must be valid in post-state.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #BBBBBB 1.0pt; mso-border-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt;" valign="top"><div class="MsoNormal">
<br /></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 0in 0in 0in 0in;" valign="top"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">_Out_writes_to_ptr_z_(p)<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #BBBBBB 1.0pt; border-left: none; border-right: solid #BBBBBB 1.0pt; border-top: none; mso-border-alt: solid #BBBBBB .75pt; mso-border-left-alt: solid #BBBBBB .75pt; mso-border-top-alt: solid #BBBBBB .75pt; padding: 7.5pt 6.0pt 7.5pt 6.0pt; width: 4.5in;" valign="top" width="432"><div class="MsoNormal">
<span style="color: #2a2a2a; font-family: "Segoe UI",sans-serif; font-size: 10.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">A
pointer to a null-terminated array for which the expression <i>p</i> – _Curr_ (that
is, <i>p</i> minus_Curr_) is defined by the appropriate language
standard. The elements prior to <i>p</i> do not have to be valid in
pre-state and must be valid in post-state.<o:p></o:p></span></div>
</td>
</tr>
</tbody></table>
<br />samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-4456208025053073472015-01-28T13:58:00.001-08:002015-01-28T13:58:35.534-08:00WRL and the ComPtrMore recently I have been forced out of my comfort zone of C-style systems programming where you manage your own memory and concurrency and in to the world of writing code for WinRT ABI.<br />
<br />
In case you don't know, WinRT (universal, modern, tailored, Windows Store?) apps can be written in C#, C++, or even *gasp* JavaScript. It actually doesn't matter which laguage you use, because they all thunk down to the WinRT ABI. The ABI is native (read: c++) code, so it is fast and efficient. Under the covers, with WinRT API is just COM, or more accurately modern COM. The MIDL syntax has been updated to make way modern runtime APIs.<br />
<br />
How does a systems programmer write modern COM for ABI code? In short, the Windows Runtime Library or WRL. Modern COM still has classic COM under the hood. One thing they tried to do was to abstract away some of the error prone aspects of COM while making it more developer-friendly. In some ways it is similar in purpose to ATL but without all of the ATL grossness. It uses ComPtr instead of CComPtr for smart pointers, and I don't totally hate them like I did CComPtrs. Modern COM uses a lot of templates types, and doesn't use exceptions. Most Windows systems programmers avoid exceptions to make the code easier to debug with the KD. Personally I also hate debugging templated code, but I guess it is needed for the generic programming concepts to work.<br />
<br />
<h2>
<span style="font-weight: normal;">ComPtr</span></h2>
<div>
ComPtr is the Modern COM smart pointer. Its behavior is similar to that of the ^ (hat) operator in WinRT CX code. ComPtr is only for COM objects, and the lifetime automatically managed. The ^ can be a smart pointer for non-COM things.</div>
<div>
<br /></div>
<div>
<br /></div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com1tag:blogger.com,1999:blog-1650318142382098495.post-23537805488072956702014-06-18T16:50:00.000-07:002014-06-18T16:50:30.424-07:00Managing ASSERT & NT_ASSERT in WinDBG & KD<h2>
What are ASSERTs and how to use them:</h2>
In general, Windows developers may use <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff542107(v=vs.85).aspx">ASSERT</a> and <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff961903(v=vs.85).aspx">NT_ASSERT</a> to validate excepted assumptions in their code. In CHK (checked non-optimized) binaries, an exception will be thrown if the expression does not evaluate to true.<br />
<br />
For example, you may have an assumption in a function, that a pointer should never be NULL and the buffer size should be less than 1k. Then you can write an ASSERT like this:<br />
<br />
ASSERT(pBuff && (cbBuff < 1024));<br />
<br />
This assertion will fire if the expression is false, or in this case: !pBuff || cbBuff >= 1024.<br />
<br />
0:003> p<br />
Assertion s:\dllsrv\info.cpp(83): pBuff && (cbBuff < 1024)<br />
...<br />
<br />
There are differences between the two, but normally it is better to use NT_ASSERT, but this is not what this article is about. There is also a NT_VERIFY which will assert even in FRE (free optimized binaries), but I can 't think of any reasons of the top of my head why you would need to use it.<br />
<br />
As a rule of thumb, you shouldn't use ASSERTs too heavily. For instance, in my example, you can validate the same thing using <a href="http://msdn.microsoft.com/en-us/library/ms235402.aspx">SAL</a> annotations where bugs can be found at compile time with static analysis tools like <a href="http://research.microsoft.com/en-us/news/features/prefast.aspx">prefast</a> which is always preferable to runtime debugging. You may consider adding ASSERTs while developing your code, and removing a bunch of them once it has stabilized.<br />
<br />
<h2>
ASSERTs in WinDBG & KD</h2>
Normally when I am testing my code, I run my code under WinDBG or KD. I normally copy private CHK versions of my binaries with symbols. It is always a good idea to enable application verifier as well, or use gflags to add standard checks.<br />
<br />
In the simplest form, lets say your ASSERT throws an exception because it evaluates false, you do the normal debugging thing and figure out why your assumptions were not correct, fix the bug(s), replace the binary, and restart the test. That is the point of the asset after all.<br />
<br />
But, lets say you want to continue on. What are the commands to do that?<br />
<br />
gh - this is the basic one. It is like pressing g or F5 except you are telling to not worry about the exception.<br />
<br />
ah - you use ah to control a specific assert. For instance, you can use ahi to ignore an assertion, if it is noisy and you don't want or can't change the binary to remove or fix it.<br />
<br />
sx - is used to control exceptions globally. sx* asrt will disable all asserts for instance.<br />
<br />
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-90197819078271419032013-07-17T16:58:00.001-07:002013-07-17T16:58:40.302-07:00Postmortem Debugging with WinDBG or NTSD<div class="MsoNormal">
I have mentioned several times before that using application
verifier will help root cause and solve many bugs like for example memory bugs
(leaks, heap corruptions, etc.), locking bugs, etc. If in user mode (UM) you can just attach the
debugger to your UM process and run your tests until in breaks in, or if in KM
you would use a KD but the same thing applies. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Let’s say that you have a heap corruption that is hard to
track down in your UM process. Normally
you would do this:<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<!--[if !supportLists]-->1.<span style="font-size: 7pt;">
</span><!--[endif]-->Isolate your code into a single process with a
unique image name.<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<!--[if !supportLists]-->2.<span style="font-size: 7pt;">
</span><!--[endif]-->Enable page heap on that image name using
gflags.<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<!--[if !supportLists]-->3.<span style="font-size: 7pt;">
</span><!--[endif]-->Start that process and attach a debugger
(windbg)<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<!--[if !supportLists]-->4.<span style="font-size: 7pt;">
</span><!--[endif]-->Reproduce the issue that causes the corruption
and watch the debugger break in<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<!--[if !supportLists]-->5.<span style="font-size: 7pt;">
</span><!--[endif]-->Then use the handy !heap –triage command to give
you some more clues as to what is going on<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Alternatively depending on what the memory problem is, in
step 2, application verifier could also help.
It can be enable on your image with appverif.exe or gflags.exe. If in KM, use driver verifier and KD. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
However with some bugs relating to race conditions, or
memory corruptions, enabling these tools on your process or attaching the debugger
its self could be enough to make it so that the issue doesn’t repro
anymore. That can be frustrating.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
If directly debugging your process causes you to lose the
repro, there are a few other techniques you can employ:<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
<!--[if !supportLists]-->-<span style="font-size: 7pt;">
</span><!--[endif]-->Tracing: adding WPP tracing to your code can be
a great way to trouble shoot some issues with your code that are hard to capture
with a debugger. This is an especially
good method for race conditions and deadlocks that don’t hit with a debugger.<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
<!--[if !supportLists]-->-<span style="font-size: 7pt;">
</span><!--[endif]-->KD: you can set up your machine for kernel
debugging. When you UM process has an
unhandled exception, then the KD will break in.
KD is always a solid choice, but kernel debugging may be harder for some
than UM debugging. Also, some machines
are hard to setup for KD like Ultrabooks where the debugable USB port may be
internal to the chassis and soldered to the web cam, or it is an ARM tablet.<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
<!--[if !supportLists]-->-<span style="font-size: 7pt;">
</span><!--[endif]-->WER: Windows Error Reporting can be configured
to capture dumps of your process when it crashes. You can debug the dump after the fact. Dump files are not as nice as debugging a
live machine, but this could be a great option where your code is deployed to a
lot of machines, and you want to see what happened on a machine where the bug
repros.<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
<!--[if !supportLists]-->-<span style="font-size: 7pt;">
</span><!--[endif]-->Postmortem Debugging: you can configure Windows
to launch and attach a debugger in response to a un handled exception. This is called postmortem debugging.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
All of these have their uses, but I will focus on postmortem
debugging because it was the only way I could chase down a heap corruption that
I have been trying to root cause for the past few days.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
First off, you can use this link to read about it in detail if
you like:<o:p></o:p></div>
<div class="MsoNormal">
<a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff542967(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/hardware/ff542967(v=vs.85).aspx</a><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The basics are:<o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
<!--[if !supportLists]-->-<span style="font-size: 7pt;">
</span><!--[endif]-->Simply type in an elevated command prompt “windbg
–I” to make windbg the postmortem debugger.
This works great for processes in your login session. <o:p></o:p></div>
<div class="MsoListParagraph" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
<!--[if !supportLists]-->-<span style="font-size: 7pt;">
</span><!--[endif]-->Use NTSD if you need to used named pipe
debugging. Type “ntsd –iae”. You can use the –iaec “extra options” to add
extra options, but it doesn’t work for –server like you need for name pipe
debugging. You need to manually edit the
reg key at \\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
NT\CurrentVersion\AeDebug. <o:p></o:p></div>
<br />
<div class="MsoNormal">
<br /></div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-84886990415446798402013-06-28T15:24:00.003-07:002013-06-28T15:24:59.247-07:00GFlags.exe and PageheapI was tracking down a heap corruption today, and it occurred to me that I haven't mentioned how to enable pageheap. For instance, when you use the handy "!heap -traige", if there was a heap corruption, sometimes it will tell to try the repro again with pageheap enabled. How do you do that?<br />
<br />
There are actually several ways to enable pageheap, but I will only talk about one, modifying the global flags using gflags.exe. It should get installed when you install windbg.<br />
<br />
Basically for a user mode (UM) process, you go to the image file tab, and type in the name of your exe. If you run in a svchost.exe, then you should probably break out your service to a uniquely named servicehost.exe. I use myhost.exe normally for debugging a service. After that, check "Enable page heap."<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnn9seDBj1FtZrRgcA1wDomA6m6mbKTHoPHVdnWKZGZbbn9hG99T4hTpNoxt6zVgZOdjeG8FkYAm4BZdewdnxTo_SJzF9ZdKLZGupk_puVEY303hKogY5q-mhbyN1UHQk_okyQ_ahC8qE/s546/gflags.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnn9seDBj1FtZrRgcA1wDomA6m6mbKTHoPHVdnWKZGZbbn9hG99T4hTpNoxt6zVgZOdjeG8FkYAm4BZdewdnxTo_SJzF9ZdKLZGupk_puVEY303hKogY5q-mhbyN1UHQk_okyQ_ahC8qE/s1600/gflags.png" title="gflags.exe" /></a></div>
<br />
Next, you need to run the code in question under the debugger, and then you reproduce the heap corruption. Normally the debugger will break in This time you will be able to get a lot more useful information out of !heap and !analyze. samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-22706038520771473962013-06-04T15:13:00.000-07:002013-11-25T11:29:35.092-08:00See the OS Version in WinDBGI seem to forget this command every so often, so it is ripe for a post. Often I will be debugging a remote KD from some other team, and I want to know what version of the OS I am debugging. The command for this is vertarget. Super obvious. Obviously the next most obvious command would be version, which is for the version of the debugger, and ver which is nothing.<br />
<br />
Here is some sample output of vertarget:<br />
<br />
0:005> vertarget<br />
Windows 8 Version 9200 MP (4 procs) Free x64 <= looks like the output of GetVersionEx which lies after 8, and always says it Windows 8.<br />
Product: WinNt, suite: SingleUserTS<br />
kernel32.dll version: 6.3.9418.0 (winmain.130530-1753) <= This looks the actual version you would get fro m RtlGetVersion<br />
Machine Name: "bob"<br />
Debug session time: Fri May 31 19:12:24.000 2013 (UTC - 7:00)<br />
System Uptime: 0 days 1:03:12.334<br />
Process Uptime: 0 days 0:16:35.000<br />
Kernel time: 0 days 0:00:00.000<br />
User time: 0 days 0:00:00.000<br />
<div>
<br />
This is what it looks like from a KD:<br />
0: kd> vertarget<br />
Windows 8 Kernel Version 9658 MP (4 procs) Free x64<br />
Product: WinNt, suite: TerminalServer SingleUserTS<br />
Built by: 9658.0.amd64fre.winmain.131120-1618<br />
Machine Name: "bobby-brown"<br />
Kernel base = 0xfffff801`d3e15000 PsLoadedModuleList = 0xfffff801`d40dfb90<br />
Debug session time: Fri Nov 22 14:28:29.746 2013 (UTC - 8:00)<br />
System Uptime: 0 days 0:45:58.445</div>
<div>
<br /></div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com1tag:blogger.com,1999:blog-1650318142382098495.post-4144249762559284592013-03-28T14:21:00.002-07:002013-03-28T14:21:40.650-07:00WinDBG: dt vs ??<h2>
dt</h2>
<div>
The dt command stands for display type.</div>
<div>
<br /></div>
<div>
usage:</div>
<div>
dt var</div>
<div>
<br /></div>
<div>
dt address</div>
<h2>
??</h2>
<div>
The ?? command is for evaluating a C++ expression. You can use it like dt, but you can use it to do even more. I personally like to just use it most of the time because C are more accessible to me often than trying to remember which switches I need to use with dt.</div>
<div>
<br /></div>
<div>
usage:</div>
<div>
?? sizeof(var)</div>
<div>
<br /></div>
<div>
?? this</div>
<div>
<br /></div>
<div>
?? this->m_member_obj</div>
<div>
<br /></div>
<div>
?? array[25].member_ptr->val</div>
<div>
<br /></div>
<div>
?? g_some_global</div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-33738276913096072472013-03-21T15:09:00.001-07:002013-03-21T15:14:57.742-07:00Checking an Event's Signaled State in KM w/ WinDBG<a href="http://samscode.blogspot.com/2012/03/windows-system-events-windbg-debugging.html">I've talked about debugging events in the past</a> in UM in simple terms. !handle works great, and although is use is slightly different in UM vs KM it provides a lot of good information, but lets say you are in KD and want to know if your event is signaled or not. !handle will not tell you that. This is how you do it. Note: you need to have a KD to look at the kernel's objects.<br />
<br />
1. Find the index of handle<br />
<br />
<br />
1: kd> dt g_hMyEvent<br />
my_bin!g_hMyEvent<br />
<span style="background-color: yellow;">0x00001218</span><br />
Void<br />
<br />
<div>
<br /></div>
<br />
2. Use !handle to get the address of the event object.<br />
<br />
1: kd> !handle <span style="background-color: yellow;">0x00001218</span> f -1 Event<br />
<br />
Searching for handles of type Event<br />
<br />
PROCESS 845f4b40 SessionId: 0 Cid: 040c Peb: 7fbb4000 ParentCid: 023c<br />
DirBase: 7ffea200 ObjectTable: a194d280 HandleCount: 1071.<br />
Image: svchost.exe<br />
<br />
Handle table at a194d280 with 1071 entries in use<br />
<br />
1218: Object: <span style="background-color: lime;">aa934288</span> GrantedAccess: 001f0003 Entry: bb591430<br />
Object: aa934288 Type: (845692b8) Event<br />
ObjectHeader: aa934270 (new version)<br />
HandleCount: 1 PointerCount: 62<br />
<div>
<br /></div>
<div>
3. Cast that pointer to the dispatch header it is</div>
<div>
<div>
1: kd> ?? (PDISPATCHER_HEADER)<span style="background-color: lime;">0xaa934288</span></div>
<div>
PDISPATCHER_HEADER 0xaa934288</div>
<div>
+0x000 Type : <span style="background-color: orange;">0</span> ''</div>
<div>
+0x001 TimerControlFlags : 0 ''</div>
<div>
+0x001 Absolute : 0y0</div>
<div>
+0x001 Wake : 0y0</div>
<div>
+0x001 EncodedTolerableDelay : 0y000000 (0)</div>
<div>
+0x001 Abandoned : 0 ''</div>
<div>
+0x001 Signalling : 0 ''</div>
<div>
+0x002 ThreadControlFlags : 0x4 ''</div>
<div>
+0x002 CycleProfiling : 0y0</div>
<div>
+0x002 CounterProfiling : 0y0</div>
<div>
+0x002 GroupScheduling : 0y1</div>
<div>
+0x002 AffinitySet : 0y0</div>
<div>
+0x002 Reserved : 0y0000</div>
<div>
+0x002 Hand : 0x4 ''</div>
<div>
+0x002 Size : 0x4 ''</div>
<div>
+0x003 TimerMiscFlags : 0 ''</div>
<div>
+0x003 Index : 0y0</div>
<div>
+0x003 Processor : 0y00000 (0)</div>
<div>
+0x003 Inserted : 0y0</div>
<div>
+0x003 Expired : 0y0</div>
<div>
+0x003 DebugActive : 0 ''</div>
<div>
+0x003 DpcActive : 0 ''</div>
<div>
+0x000 Lock : 0n262144</div>
<div>
+0x000 LockNV : 0n262144</div>
<div>
<span style="background-color: cyan;">+0x004 SignalState : 0n1</span></div>
<div>
+0x008 WaitListHead : _LIST_ENTRY [ 0xaa934290 - 0xaa934290 ]</div>
</div>
<div>
<br /></div>
<div>
There you go, you can see this event is in a signaled state.<br />
<br />
By the way, the member <span style="background-color: orange;">Type 0</span> means event notification. Other common values:<br />
<br />
EventNotificationObject = 0,<br />
EventSynchronizationObject = 1,<br />
MutantObject = 2,<br />
ProcessObject = 3,<br />
QueueObject = 4,<br />
SemaphoreObject = 5,<br />
ThreadObject = 6,<br />
<br />
<br />
<br /></div>
<div>
<br /></div>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0tag:blogger.com,1999:blog-1650318142382098495.post-28774187140085352442013-03-05T17:48:00.004-08:002013-03-05T17:51:02.822-08:00Setting FILETIME Timeout for SetThreadpoolWaitUsing Window's new (since Vista) Threadpool is great. You can <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms686760(v=vs.85).aspx">read up on it here</a>. If you want some sample code on usage patterns, message me, and I can do a post on it later.<br />
<div>
<br /></div>
<div>
The threadpool has a generic wait on an handle (eg. event, process, etc.) mechanism. It even has a timeout so say you want to wait either for an event or a timeout, but the timeout is in FILETIME format. How do you convert a specified amount say in ms of time into a FILETIME?</div>
<div>
<br /></div>
<div>
<br /></div>
<pre>HRESULT DoWaitWithTimeout(
__in DWORD Timeout) // in ms
{
HRESULT hr = S_OK;
PMY_CONTEXT pContext = NULL;
FILETIME timeout = {0};
pContext = (PMY_CONTEXT)my_alloc(sizeof(MY_CONTEXT));
if (!pContext) {
hr = E_OUTOFMEMORY;
goto Exit;
}
ZeroMemory(pContext, sizeof(MY_CONTEXT));
pContext->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!pContext->hEvent) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
pContext->hWait = CreateThreadpoolWait(
MyWaitCallback,
pContext,
NULL);
if (!pContext->hWait) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
if (Timeout) {
ULARGE_INTEGER ulTimeout = {0};
// Timeout in ms, FILETIME is in 100 ns increments
ulTimeout.QuadPart = Timeout * -10000;
timeout.dwHighDateTime = ulTimeout.HighPart;
timeout.dwLowDateTime = ulTimeout.LowPart;
}
SetThreadpoolWait(
pContext->hWait,
pContext->hEvent,
&timeout);
</pre>
<pre>// ...</pre>
<pre></pre>
<pre></pre>
<pre></pre>
samhttp://www.blogger.com/profile/02833051520277478446noreply@blogger.com0