Bug in srchadmin.dll


A few days after my brother installed Windows 8 Developer Preview he told me that when he clicks on the "File Types" in Control Panel Indexing Options->Advanced, both dialogues (Indexing Options and Advanced Options) disappear in a few seconds.

The first step that I did was a Web search with the text "Indexing Options Advanced error". I found that the problem is not only in Windows 8 Developer Preview, but in Windows 7 too. It is worth noting that on my system (Windows 7 Enterprise SP1) everything works fine. Because there is no solution, even for Windows 7, I decided to look under the hood.

To find the PID of the process that owns the dialog "Advanced Options" I used the feature of the Process Explorer "Find Window's Process".

PID

Then I launched WinDbg and attached it to the dllhost.exe

(fa8.fa4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
srchadmin!CFileTypesPage::_OnNotify+0x173:
000007fb`0a74f3c3 488b01          mov     rax,qword ptr [rcx] ds:ffffffff`8f064c80=????????????????
0:003> k
Child-SP          RetAddr           Call Site
000000cf`8c1bbe40 000007fb`0a74eab9 srchadmin!CFileTypesPage::_OnNotify+0x173
000000cf`8c1bbf00 000007fb`186facf9 srchadmin!CFileTypesPage::s_DialogProc+0xb5
000000cf`8c1bbf40 000007fb`186faaa3 user32!UserCallDlgProcCheckWow+0x135
000000cf`8c1bc010 000007fb`186fa9ce user32!DefDlgProcWorker+0xb3
000000cf`8c1bc0e0 000007fb`186fb51a user32!DefDlgProcW+0x56
000000cf`8c1bc120 000007fb`186f9178 user32!UserCallWinProcCheckWow+0x13a
000000cf`8c1bc1e0 000007fb`186f931d user32!SendMessageWorker+0x18f
000000cf`8c1bc280 000007fb`158f4593 user32!SendMessageW+0x125
000000cf`8c1bc2e0 000007fb`158f84b4 comctl32!CCSendNotify+0xfc7
000000cf`8c1bc400 000007fb`158f8485 comctl32!CICustomDrawNotify+0x22
000000cf`8c1bc430 000007fb`1593ada5 comctl32!CIFakeCustomDrawNotify+0x21
000000cf`8c1bc460 000007fb`15a474c4 comctl32!CLVDrawItemManager::BeginFakeItemDraw+0x51
000000cf`8c1bc490 000007fb`15a3f3c3 comctl32!CLVDrawItemManager::ComputeTextWidth+0xbc
000000cf`8c1bc740 000007fb`15a3f806 comctl32!CLVHeaderControlManager::_ComputeColumnWidthForItem+0x127
000000cf`8c1bc7e0 000007fb`159d4d58 comctl32!CLVHeaderControlManager::_GetAutoWidth+0x41a
000000cf`8c1bc9c0 000007fb`15988826 comctl32!CLVHeaderControlManager::SetColumnWidth+0x6c
000000cf`8c1bcab0 000007fb`159888be comctl32!CLVListView::SetColumnWidthEx+0x1a7
000000cf`8c1bcae0 000007fb`15932351 comctl32!CListView::SetColumnWidth+0x22
000000cf`8c1bcb10 000007fb`158f180e comctl32!CListView::WndProc+0x17ca
000000cf`8c1bcd80 000007fb`186fb51a comctl32!CListView::s_WndProc+0x6bd
000000cf`8c1bcde0 000007fb`186f9178 user32!UserCallWinProcCheckWow+0x13a
000000cf`8c1bcea0 000007fb`186f931d user32!SendMessageWorker+0x18f
000000cf`8c1bcf40 000007fb`0a74eeb7 user32!SendMessageW+0x125
000000cf`8c1bcfa0 000007fb`0a74eaa9 srchadmin!CFileTypesPage::_OnInitDialog+0x3a7
000000cf`8c1bd2d0 000007fb`186fb091 srchadmin!CFileTypesPage::s_DialogProc+0xa5
000000cf`8c1bd310 000007fb`186faaa3 user32!UserCallDlgProcCheckWow+0x18b
000000cf`8c1bd3e0 000007fb`186fa9ce user32!DefDlgProcWorker+0xb3
000000cf`8c1bd4b0 000007fb`186fb51a user32!DefDlgProcW+0x56
000000cf`8c1bd4f0 000007fb`186f9178 user32!UserCallWinProcCheckWow+0x13a
000000cf`8c1bd5b0 000007fb`186eada9 user32!SendMessageWorker+0x18f
000000cf`8c1bd650 000007fb`186eb4ab user32!InternalCreateDialog+0x962
000000cf`8c1bd7e0 000007fb`186eb6fb user32!CreateDialogIndirectParamAorW+0x5b
000000cf`8c1bd830 000007fb`15996d93 user32!CreateDialogIndirectParamW+0x1b
000000cf`8c1bd870 000007fb`159971ca comctl32!_CreatePageDialog+0xb0
000000cf`8c1bd8c0 000007fb`15996ecb comctl32!_CreatePage+0x162
000000cf`8c1bd900 000007fb`159415ff comctl32!PageChange+0xd0
000000cf`8c1bdb80 000007fb`186facf9 comctl32!PropSheetDlgProc+0x372
000000cf`8c1bdc80 000007fb`186faaa3 user32!UserCallDlgProcCheckWow+0x135
000000cf`8c1bdd50 000007fb`186fa9ce user32!DefDlgProcWorker+0xb3
000000cf`8c1bde20 000007fb`186fb51a user32!DefDlgProcW+0x56
000000cf`8c1bde60 000007fb`186f9178 user32!UserCallWinProcCheckWow+0x13a
000000cf`8c1bdf20 000007fb`186f931d user32!SendMessageWorker+0x18f
000000cf`8c1bdfc0 000007fb`158f4593 user32!SendMessageW+0x125
000000cf`8c1be020 000007fb`1593ea1d comctl32!CCSendNotify+0xfc7
000000cf`8c1be140 000007fb`15972d75 comctl32!SendNotifyEx+0x78
000000cf`8c1be1b0 000007fb`159734a0 comctl32!ChangeSel+0x2e2
000000cf`8c1be260 000007fb`15973411 comctl32!Tab_OnLButtonDown+0x103
000000cf`8c1be2d0 000007fb`186fb51a comctl32!Tab_WndProc+0x52e
000000cf`8c1be3a0 000007fb`186fb898 user32!UserCallWinProcCheckWow+0x13a
000000cf`8c1be460 000007fb`186fbe91 user32!DispatchMessageWorker+0x1a7
000000cf`8c1be4e0 000007fb`159a5bda user32!IsDialogMessageW+0x2a9
000000cf`8c1be570 000007fb`159a5b59 comctl32!Prop_IsDialogMessage+0x1f0
000000cf`8c1be5e0 000007fb`15995dbc comctl32!_RealPropertySheet+0x37f
000000cf`8c1be6e0 000007fb`0a75cb17 comctl32!_PropertySheet+0x4e
000000cf`8c1be710 000007fb`0a7533c0 srchadmin!PropertySheetW+0x5b
000000cf`8c1be740 000007fb`0a75300f srchadmin!CAdvancedOptions::Show+0x2dc
000000cf`8c1bec50 000007fb`183a6a15 srchadmin!CAdvancedOptionsComWrapper::ShowModalDialog+0x7b
000000cf`8c1becb0 000007fb`183a417b RPCRT4!Invoke+0x65
000000cf`8c1bed00 000007fb`18393696 RPCRT4!NdrStubCall2+0x371
000000cf`8c1bf340 000007fb`18c18ddf RPCRT4!NdrStubCall3+0xe0
000000cf`8c1bf3a0 000007fb`18c18d3c combase!CStdStubBuffer_Invoke+0x67
000000cf`8c1bf3d0 000007fb`18b33927 combase!SyncStubInvoke+0x60
000000cf`8c1bf440 000007fb`18c1e87b combase!CCtxComChnl::ContextInvoke+0x27d
000000cf`8c1bf670 000007fb`18b7d84a combase!ComInvokeWithLockAndIPID+0xb58
000000cf`8c1bf940 000007fb`186fb51a combase!ThreadWndProc+0x2ca
000000cf`8c1bf9d0 000007fb`186fb898 user32!UserCallWinProcCheckWow+0x13a
000000cf`8c1bfa90 000007fb`18b63f69 user32!DispatchMessageWorker+0x1a7
000000cf`8c1bfb10 000007fb`18b64104 combase!CDllHost::STAWorkerLoop+0x95
000000cf`8c1bfb70 000007fb`18b31e54 combase!CDllHost::WorkerThread+0xc0
000000cf`8c1bfbd0 000007fb`18b31f73 combase!CRpcThread::WorkerLoop+0x24
000000cf`8c1bfc10 000007fb`18a13cdc combase!CRpcThreadCache::RpcWorkerThreadEntry+0x53
000000cf`8c1bfc40 000007fb`1abf3c85 KERNEL32!BaseThreadInitThunk+0x18
000000cf`8c1bfc70 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
0:003> ub .+6
srchadmin!CFileTypesPage::_OnNotify+0x15b:
000007fb`0a74f3ab 0f854b020000    jne     srchadmin!CFileTypesPage::_OnNotify+0x3ac (000007fb`0a74f5fc)
000007fb`0a74f3b1 41399ed8020000  cmp     dword ptr [r14+2D8h],ebx
000007fb`0a74f3b8 7421            je      srchadmin!CFileTypesPage::_OnNotify+0x18b (000007fb`0a74f3db)
000007fb`0a74f3ba 48634a48        movsxd  rcx,dword ptr [rdx+48h]
000007fb`0a74f3be 4885c9          test    rcx,rcx
000007fb`0a74f3c1 740a            je      srchadmin!CFileTypesPage::_OnNotify+0x17d (000007fb`0a74f3cd)
000007fb`0a74f3c3 488b01          mov     rax,qword ptr [rcx]
000007fb`0a74f3c6 ff5008          call    qword ptr [rax+8]
0:003> dd @rdx+48h l1
000000cf`8c1bc908  8f064c80
0:003> .formats 8f064c80
Evaluate expression:
  Hex:     00000000`8f064c80
  Decimal: 2399554688
  Octal:   0000000000021701446200
  Binary:  00000000 00000000 00000000 00000000 10001111 00000110 01001100 10000000
  Chars:   ......L.
  Time:    ***** Invalid
  Float:   low -6.62144e-030 high 0
  Double:  1.18554e-314

The wrong pointer was obtained due to extending 32-bit value to 64-bit address. But thing is that it doesn’t need to extend.

0:003> dq @rdx+48h l1
000000cf`8c1bc908  000000cf`8f064c80
0:003> ln poi(poi(000000cf`8f064c80) + 8 )
(000007fb`0a74fc64)   srchadmin!CExtensionInfo::IsReadOnly   |  (000007fb`0a74fc84)   srchadmin!CExtensionExclusionsPolicy::Init
Exact matches:
    srchadmin!CExtensionInfo::IsReadOnly = <no information type>

The root cause of the problem was found and I decide to take a look how it works in Windows 7.

0:005> u srchadmin!CFileTypesPage::_OnNotify+0x16a
srchadmin!CFileTypesPage::_OnNotify+0x16a:
000007fe`f5a40496 48634a48        movsxd  rcx,dword ptr [rdx+48h]
000007fe`f5a4049a 483bcb          cmp     rcx,rbx
000007fe`f5a4049d 7408            je      srchadmin!CFileTypesPage::_OnNotify+0x17b (000007fe`f5a404a7)
000007fe`f5a4049f 488b01          mov     rax,qword ptr [rcx]
000007fe`f5a404a2 ff5008          call    qword ptr [rax+8]
000007fe`f5a404a5 8bf8            mov     edi,eax
000007fe`f5a404a7 b908000000      mov     ecx,8
000007fe`f5a404ac 3bfb            cmp     edi,ebx
0:005> dd @rdx+48h l1
00000000`0266cc88  02497a50
0:005> .formats 02497a50
Evaluate expression:
  Hex:     00000000`02497a50
  Decimal: 38369872
  Octal:   0000000000000222275120
  Binary:  00000000 00000000 00000000 00000000 00000010 01001001 01111010 01010000
  Chars:   .....IzP
  Time:    Sun Mar 21 04:17:52 1971
  Float:   low 1.48022e-037 high 0
  Double:  1.89572e-316
0:005> dq @rdx+48h l1
00000000`0266cc88  00000000`02497a50
0:005> ln poi(poi(00000000`02497a50) + 8 )
(000007fe`f5a40d88)   srchadmin!CExtensionInfo::IsReadOnly   |  (000007fe`f5a40da8)   srchadmin!CExtensionExclusionsPolicy::Init
Exact matches:
    srchadmin!CExtensionInfo::IsReadOnly = <no information type>

In Windows 7 pretty much the same code but it works well. The question is how? The answer is that the stack is never allocated higher than 0x7FFFFFFF. To make this code work properly it needs to be changed from movsxd rcx,dword ptr [rdx+48h] to mov rcx,qword ptr [rdx+48h].