Posted on 2000-03-02
Last Modified: 2013-11-20
Can somebody tell me what is wrong with this piece of code??
pShNM doesn't points to an SHNAMEMAPPING struct

TCHAR from[256];
TCHAR to[256];

_tcscpy(from, _T("c:\\adobeapp\\test.txt"));
_tcscpy(to, _T("c:\\test.txt"));
from[_tcslen(from) +1]=0;

memset(&shfo, 0x00, sizeof(shfo));
shfo.hwnd = AfxGetMainWnd()->m_hWnd;
shfo.wFunc = FO_COPY;
shfo.pFrom = from;
shfo.pTo = to;

if (0 == ::SHFileOperation(&shfo))
    if (shfo.hNameMappings)
      SHNAMEMAPPING nameMapping;

        // try to obtain a pointer
        // to the first (and in this
        // case the only)
      // SHNAMEMAPPING struct of the
        // structure pointed to by
        // shfo.hNameMappings

        // THIS IS THE PROBLEM: pShNM doesn't point to an
        // SHNAMEMAPPING struct when the file being operated on
        // was renamed by the file system
      SHNAMEMAPPING* pShNM =   (SHNAMEMAPPING*)((char*)shfo.hNameMappings + sizeof(int));


The docs say the following: "Treat hNameMappings as a pointer to a structure whose first member is an INT value, followed by an array of SHNAMEMAPPING structures. The INT value will be set to the number of structures in the array. Each SHNAMEMAPPING structure will contain the old and new path name for one of the renamed files."

The first member of the struct pointed to by SHFILEOPSTRUCT.hNameMappings (the number of SHNAMEMAPPING structs that will follow this int value) seems correct but the bytes that follow this integer value are just junk ... and not an SHNAMEMAPPING struct
Environment: NT4 SP5 IE5.0
(maybe it's something trivial but I don't know what I'm doing wrong)
Question by:searching
  • 7

Author Comment

ID: 2577814
Adjusted points to 150

Expert Comment

ID: 2577843
I think under NT SHNAMEMAPPING includes UNICODE strings. So you would have to convert them.

SHNAMEMAPPING* pShNM =   (SHNAMEMAPPING*)((char*)shfo.hNameMappings + sizeof(int));

TCHAR szOldPath[MAX_PATH] = {0};
WideCharToMultiByte(CP_ACP, 0, reinterpret_cast<LPWSTR>(pShNM->pszOldPath), MAX_PATH, szOldPath, MAX_PATH, NULL, NULL );

Under Win95 you should not have this problem


Author Comment

ID: 2579251
Edited text of question.

Author Comment

ID: 2579275
Edited text of question.
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline


Author Comment

ID: 2579279
Adjusted points to 200

Author Comment

ID: 2579280
I checked the memory pointed to by pShNM and it doesn't points to a wide character version of an SHNAMEMAPPING struct ...
Anyway tnx for the tip gelbert, all further suggestions are welcome ...

Author Comment

ID: 2579678
Adjusted points to 225
LVL 30

Accepted Solution

Zoppo earned 225 total points
ID: 2580297
I think I've found it:

It seems MSDN's description is buggy. The hNameMappings does NOT point to an int followed by an array of SHNAMEMAPPING structures. It points to an int follows by an array of pointers to SHNAMEMAPPING structures.

I.e. following code works on my system:

SHNAMEMAPPING* pShNM =   (SHNAMEMAPPING*)*( (int*)shfo.hNameMappings + 1 );
TCHAR szOldPath[MAX_PATH] = {0};
TCHAR szNewPath[MAX_PATH] = {0};
WideCharToMultiByte(CP_ACP, 0, reinterpret_cast<LPWSTR>(pShNM->pszOldPath), MAX_PATH, szOldPath, MAX_PATH, NULL, NULL );
WideCharToMultiByte(CP_ACP, 0, reinterpret_cast<LPWSTR>(pShNM->pszNewPath), MAX_PATH, szNewPath, MAX_PATH, NULL, NULL );
printf( "Renamed %s to %s\n", szOldPath, szNewPath );

hope that helps,


Author Comment

ID: 2580712
Many tnx Zoppo, you deserve the points!

BTW: In my opinion it's awfull that MS don't describe this bug in their Knowledge Base, after all this function exists since the introduction of Win32 if I'm not wrong ...

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Here's a very brief overview of the methods PRTG Network Monitor ( offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now