Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

SHFileOperation with FOF_WANTMAPPINGHANDLE ??

Posted on 2000-03-02
9
Medium Priority
?
752 Views
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

SHFILEOPSTRUCT      shfo;
TCHAR from[256];
TCHAR to[256];

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

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

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));
            }

            ::SHFreeNameMappings((HANDLE)shfo.hNameMappings);
}

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)
0
Comment
Question by:searching
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
9 Comments
 

Author Comment

by:searching
ID: 2577814
Adjusted points to 150
0
 
LVL 8

Expert Comment

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

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

0
 

Author Comment

by:searching
ID: 2579251
Edited text of question.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:searching
ID: 2579275
Edited text of question.
0
 

Author Comment

by:searching
ID: 2579279
Adjusted points to 200
0
 

Author Comment

by:searching
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 ...
0
 

Author Comment

by:searching
ID: 2579678
Adjusted points to 225
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 900 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,

ZOPPO
0
 

Author Comment

by:searching
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 ...
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
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.
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
Suggested Courses

618 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