devblogs.microsoft.com/oldnewthing
How can I use ReadDirectoryChangesW to know when someone is copying a file out of the directory?
A customer was using ReadDirectoryChangesW in the hopes of receiving a notification when a file was copied. They found that when a file was copied, they received a FILE_ NOTIFY_ CHANGE_ LAST_ ACCESS , but only once an hour . And they also got that notification even for operations unrelated to file copying. Recall that ReadDirectoryChangesW and FindFirstChangeNotification are for detecting changes to information that would appear in a directory listing . Your program can perform a FindFir...
Why doesn’t the system let you declare your own messages to have the same semantics as WM_COPYDATA?
In a comment on my discussion on how to return results back from the WM_ COPYDATA message , Jan Ringoš observed that it felt wasteful that there was this entire infrastructure for copying blocks of memory via a window message, yet only one message uses it! “ I always thought something like EnableWindowMessageDataCopy (HWND, UINT, .) after RegisterWindowMessage and ChangeWindowMessageFilterEx to get application’s own private WM_COPYDATA would be a little more secure and convenient, s...
The cover of C++: The Programming Language raises questions not answered by the cover
The book C++: The Programming Language ¹ (Waylon Warren, editor) claims to present “the complex subject of C++ in the most comprehensible and easy to understand language.” A rather overdone book blurb, in my opinion. Anyway, the book does have an attractive cover, or at least an inoffensive one. But wait, let’s zoom in on the code shown on the computer monitor. function updatePhotoDescription() { if (descriptions.length > (page * 9) + (currentImage.substring(⟦ blurry ⟧')) { ...
Before you check if an update caused your problem, check that it wasn’t a problem before the update
My colleagues over in enterprise product support often get corporate customers who report that “Your latest update broke our system.” After studying the problem (which is usually quite laborious because they have to go back and forth with the customer to capture logs and dumps and traces), they eventually conclude that, actually, the system was broken even before the upgrade! Their prediction is that if the customer takes an affected system and rolls back the update, it will still be...
A question about the maximimum number of values in a registry key raises questions about the question
A customer wanted to know the maximum number of values that can be stored in a single registry key. They found that they ran into problems when they reached a certain number of values, which was well over a quarter million. Okay, wait a second. Why are you adding over a quarter million values to a registry key!? The customer explained that they mark every file in their installer as msidbComponentAttributesSharedDllRefCount , to avoid the problem described in the documentation . And when I ...
What if a dialog wants to intercept its own message loop?
So far, we’ve been looking at how a dialog box owner can customize the dialog message loop. But what about the dialog itself? Can the dialog customize its own dialog message loop? Sure. It just has to steal the messages from its owner. The dialog box can subclass its owner and grab the WM_ ENTERIDLE message. Now, maybe it should be careful only to grab WM_ ENTERIDLE messages that were triggered by that dialog and not accidentally grab messages that were triggered by other dialogs. HANDLE...
Why doesn’t WM_ENTERIDLE work if the dialog box is a MessageBox?
Last time, we looked at how the owner of a dialog can take control just before the dialog box message loop goes idle. I said that I pulled a trick. The trick is that I used the common file open dialog instead of a simple MessageBox . Indeed, if you replace the call to GetOpenFileName with a call to MessageBox , then no WM_ ENTERIDLE message arrives, and you get no beeping. What’s going on? A dialog can suppress the WM_ ENTERIDLE message by adding the DS_ NOIDLEMSG dialog style to ...
How can I change a dialog box’s message loop to do a MsgWaitForMultipleObjects instead of GetMessage?
A customer wanted to know how to change a dialog box’s message loop so that it used MsgWaitForMultipleObjects instead of GetMessage . (I’m guessing that they had a handle that they wanted to wait on while the dialog was up.) The standard dialog box message loop checks only for messages, not kernel handles. One way to do it is to replace the modal dialog box with a modeless one and run your own message loop . However, there’s a key piece missing from the do-it-yourself, whi...
Windows 95 defenses against installers that overwrite a file with an older version
Back in the days of 16-bit Windows, many system components were redistributable, meaning that programs that used those components could include a copy of those system components and install them onto the system as part of the program’s installer. The guidance for installing the system components was that if the installer finds a copy of the system component already on the system, then they should compare the version number of the existing file with the version number of the file being inst...
How can I make sure the anti-malware software doesn’t terminate my custom service?
A customer was developing a Windows service process, and it is important to them that the service keep running on their servers. They wanted to know if there was a way they could prevent users who connect to the server from terminating the service. In particular, they wanted to make sure that the user couldn’t use the anti-malware software to terminate their service, either by mistake or maliciously. The fact that they made it to asking about anti-malware software tells me that they have a...
Windows stack limit checking retrospective: arm64, also known as AArch64
Our survey of stack limit checking wraps up with arm64, also known as AArch64. The stack limit checking takes two forms, one simple version for pure arm64 processes, and a more complex version for Arm64EC. I’m going to look at the simple version. The complex version differs in that it has to check whether the code is running on the native arm64 stack or the emulation stack before calculating the stack limit. That part isn’t all that interesting. ; on entry, x15 is the number of parag...
Windows stack limit checking retrospective: amd64, also known as x86-64
Our survey of stack limit checking reaches the modern day with amd64, also known as x86-64. This time, there are two versions of the function, one for user mode and one for kernel mode. We’ll look at the user mode version. Actually, there are two user mode versions. One is in msvcrt , the legacy runtime. ; on entry, rax is the number of bytes to allocate ; on exit, stack has been validated (but not adjusted) chkstk: sub rsp, 16 mov [rsp], r10 ; save temporary register mov [rsp][8], r11 ; s...
Windows stack limit checking retrospective: Alpha AXP
We continue our historical survey of Windows stack-checking functions by looking at the Alpha AXP. ; on entry, t12 is the number of bytes to allocate ; on exit, stack has been validated (but not adjusted) ; modifies t8, t9, t10 _chkstk: subq sp, t12, t8 ; t8 = new stack pointer mov v0, t10 ; save v0 in t10 (call_pal will overwrite it) bgt sp, usermode ; branch if running in user mode call_pal rdksp ; PAL call to get start of kernel stack in v0 lda t9, -KERNEL_STACK_SIZE(v0) ; t9 = end of stack b...
Windows stack limit checking retrospective: x86-32 also known as i386, second try
The last time we looked at the Windows stack limit checker on x86-32 (also known as i386) , we noted that the function has changed over the years. Here’s the revised version. _chkstk: push ecx ; remember desired allocation size lea ecx, [esp][4] ; ecx = original stack pointer - 4 sub ecx, eax ; ecx = new stack pointer - 4 sbb eax, eax ; clamp ecx to zero if underflow not eax and ecx, eax mov eax, esp ; round current stack pointer and eax, -PAGE_SIZE ; to page boundary ; eax = most recently...
Windows stack limit checking retrospective: PowerPC
We continue our historical survey of Windows stack-checking functions by looking at the PowerPC. The weird thing here is that on PowerPC, you ask for the negative of the stack frame size. We’ll see why soon. ; on entry, r12 is the *negative* of the number of bytes to allocate ; on exit, stack has been validated (but not adjusted) chkstk: subi r0, r12, PAGE_SIZE - 1 ; expand by another page to make sure we get it all ; get the stack limit for the current stack cmpwi sp, 0 ; check what kind ...
Windows stack limit checking retrospective: MIPS
Last time, we looked at how the 80386 performed stack probing on entry to a function with a large local frame . Today we’ll look at MIPS, which differs in a few ways. ; on entry, t8 = desired stack allocation chkstk: sw t7, 0(sp) ; preserve register sw t8, 4(sp) ; save allocation size sw t9, 8(sp) ; preserve register li t9, PerProcessorData ; prepare to get thread bounds bgez sp, usermode ; branch if running in user mode subu t8, sp, t8 ; t8 = new stack pointer (in delay slot) lw t9, Kerne...
Windows stack limit checking retrospective: x86-32, also known as i386
We start our survey of historical stack limit checking functions on Windows with the 80386 family of processors. This function has actually changed form over the years, so we’ll start with the “original flavor”. Originally, the _chkstk function was called by putting the desired number of bytes in the eax register and calling the _chkstk function. The function touched each page of the stack, adjusted the stack pointer, and then returned with the adjusted stack pointer . This is ...
How do compilers ensure that large stack allocations do not skip over the guard page?
Some time ago we took a closer look at the stack guard page and how a rogue stack access from another thread into the guard page could result in the guard page being lost. (And we used this information to investigate a stack overflow failure .) You might have noticed that the “one guard page at a time” policy assumes that the stack grows one page at a time. But what if a function has a lot of local variables (or just one large local variable) such that the size of the local frame is ...
A snappy answer when asked about dressing casually at IBM
I noted in the past that Microsoft engineers had trouble fitting into the IBM corporate culture when on temporary assignment at IBM offices in Boca Raton, Florida. In particular, they struggled with so-called “security violations “. I noted that one such category of security violation was “wearing shorts to work.” Bearing this in mind, you may appreciate this brief incident. One of the Microsoft developers beeped his badge to enter the building while wearing his usual sho...
The fine print giveth and the bold print taketh away: The countdown timer
Some time ago, I was purchasing online tickets to an event. When I got to the end of the checkout flow, I got this: Your seats will be held for only a limited time. If you do not complete your transaction in time, your seats will be released. Time remaining: 3 2 1 0 : 00 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00¹ You must accept the following terms to complete...