Possibly a late answer, but I too had to deal with this issue and wanted to present my solutions in case others encounter this in the future (my condolences if you do). For those that wonders why use legacy GetOpenFileName(), if you are stuck with legacy .NET 1.1 and due to restrictions (in a real world, there are times when the person or organizations that are paying you to do this requires it), we have no other choices but to be bound to it, so please leave the criticisms aside and stick with OP's question. Also, one nice feature (I'm sure people can correct me on this) is that this method does not actually open the file when ALLOWMULTISELECT is set, thus you can use it as an interface to choose multiple files without eating the resources of each files opened as streams (i.e. imagine multi-selecting 1000+ files and each had a stream opened for it! - NOTE: .NET's OpenFileDialog also can do this since you have to explicitly call OpenFile() method to open the resources, thus iteration of Filenames property is possible, though it may give "InvalidOperationException: Too many files selected" if you exceed the mystery limits I've no clue about).
Firstly, despite what https://msdn.microsoft.com/en-us/library/windows/desktop/ms646927%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 says in the remarks as
Note, when selecting multiple files, the total character limit for the file names depends on the version of the function.
• ANSI: 32k limit
• Unicode: no restriction
Whether you explicitly call the "GetOpenFileNameW()" or let it internally switch to it, there is a 32KB limit on Windows XP (as OP mentions as well). Though I've not time to investigate, on Win7 and Server 2012 (64-bits), the same API call will switch correctly (apparently) to Unicode mode and bypasses the 32KB limit.
I've discovered that after reading the MSDN article on https://msdn.microsoft.com/en-us/library/ms996463.aspx?f=255&MSPPError=-2147217396 , If I trap WM_NOTIFY for CDN_SELCHANGE, query then for CDM_GETSPEC with a buffer that is quite large (i.e. greater than 32KB), you can in fact capture file list/collections greater than the 32KB limit. My apologies that the solution described in the MSDN article is C# and not C++, but the end-result should be the same.