// Here's the chunk of code in exec.c that I instrumented myself.
// I also made it so the NSIS logging outputs ms (milliseconds).
// This is inside the function ExecuteEntry.

//...
    case EW_WRITEUNINSTALLER:
      {
				  
        int ret=-666;
        HANDLE hFile;
        char *buf0=GetStringFromParm(0x00);
		log_printf( "case EW_WRITEUNINSTALLER found, checking valid path spec" );
        if (validpathspec(buf0))
        {
			log_printf2( "path spec valid: %s", buf0 );
          mystrcpy(buf1,buf0);
        }
        else
        {
			log_printf2( "path spec not valid: %s", buf0 );
          lstrcat(addtrailingslash(mystrcpy(buf1,state_install_directory)),buf0);
        }
		log_printf2( "validating filename %s", buf1 );
        validate_filename(buf1);

		log_printf4( "opening file %s with params %d, %d", buf1, GENERIC_WRITE, CREATE_ALWAYS );
        hFile=myOpenFile(buf1,GENERIC_WRITE,CREATE_ALWAYS);
        if (hFile != INVALID_HANDLE_VALUE)
        {
		
          unsigned char *filebuf;
          int filehdrsize = g_filehdrsize;
		  log_printf( "file is a valid handle" );
          filebuf=(unsigned char *)my_GlobalAlloc(filehdrsize);
          if (filebuf)
          {
			  
            DWORD lout;
			log_printf2( "filebuf is valid: %d", filebuf );
            SetSelfFilePointer(0);
			log_printf2( "reading self file with filehdrsize=%d", filehdrsize );
            ReadSelfFile((char*)filebuf,filehdrsize);
            {
              unsigned char* seeker;
				
              unsigned char* unicon_data = seeker = (unsigned char*)my_GlobalAlloc(parm2);
			  log_printf2( "just set unicon_data from my_GlobalAlloc(%d)", parm2 );
              if (unicon_data) {
				  log_printf4( "unicon_data exists, getting compressed data from block to memory using: %d, %s, %d", parm1,unicon_data,parm2 );
                GetCompressedDataFromDataBlockToMemory(parm1,unicon_data,parm2);
                while (*seeker) {
                  struct icondata {
                    DWORD dwSize;
                    DWORD dwOffset;
                  } id = *(struct icondata *) seeker;
                  seeker += sizeof(struct icondata);
				  log_printf2( "inside loop, seeker is %d", seeker );
                  mini_memcpy(filebuf+id.dwOffset, seeker, id.dwSize);
					log_printf2( "inside loop, adding %d to seeker", id.dwSize );
                  seeker += id.dwSize;
                }
				log_printf( "freeing unicon_data" );
                GlobalFree(unicon_data);
              }
            }
			log_printf4( "writing file %d with size %d and filebuf %s", hFile, filehdrsize, filebuf );
            WriteFile(hFile,(char*)filebuf,filehdrsize,&lout,NULL);
			log_printf( "freeing filebuf" );
            GlobalFree(filebuf);
			log_printf( "GetCompressedDataFromDataBlock..." );
            ret=GetCompressedDataFromDataBlock(-1,hFile);
			log_printf2( "...returned %d", ret );
          }
			log_printf( "CloseHandle" );
          CloseHandle(hFile);
        }
		

        log_printf3("created uninstaller: %d, \"%s\"",ret,buf1);
//...







// Here's what I get in my logs for a failure case:

 ms 1221565 reading self file with filehdrsize=39424
 ms 1221565 just set unicon_data from my_GlobalAlloc(756)
 ms 1221565 unicon_data exists, getting compressed data from block to memory using: 18038326, , 756
 ms 1354353 inside loop, seeker is 3219784
 ms 1354353 inside loop, adding 744 to seeker
 ms 1354353 freeing unicon_data
 ms 1354353 writing file 288 with size 39424 and filebuf MZ
 ms 1354353 freeing filebuf
 ms 1354353 GetCompressedDataFromDataBlock...
 ms 1355118 ...returned 103591
 ms 1355118 CloseHandle
