
// windebug.c

// just some DEBUG stuff

#include <config.h>
#include <system.h>
#include <common.h>
#include <lmerr.h>   /* for NERR_BASE, ... */

DWORD dw_winLastError = 0;
static HANDLE hOutFile = NULL;
void win_Create_Log_File( void )
{
   hOutFile = CreateFile(DEF_LOG_FILE,
      GENERIC_WRITE,
      FILE_SHARE_READ,
      NULL,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL,
      NULL);
}

HANDLE win_GetOutHandle( void ) { return hOutFile; }

char * GetWinErrorText( char * lpszBuf, DWORD dwSize, DWORD dwError ) 
{
   LPSTR MessageBuffer;
   DWORD dwBufferLength;
   DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_IGNORE_INSERTS |
        FORMAT_MESSAGE_FROM_SYSTEM ;
   HMODULE hModule = NULL; // default to system source

   dw_winLastError = dwError;
   sprintf(lpszBuf, "Error %d", dwError );
   if(dwError >= NERR_BASE && dwError <= MAX_NERR)
   {
      hModule = LoadLibraryEx( TEXT("netmsg.dll"),
         NULL,
         LOAD_LIBRARY_AS_DATAFILE );

      if(hModule != NULL)
         dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
   }

   // Call FormatMessage() to allow for message 
   //  text to be acquired from the system 
   //  or from the supplied module handle.

   if( dwBufferLength = FormatMessageA (
      dwFormatFlags,
      hModule, // module to get message from (NULL == system)
      dwError,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
      (LPSTR) &MessageBuffer,
      0,
      NULL ))
   {
      if( dwBufferLength > dwSize )
      {
         strncpy( lpszBuf, MessageBuffer, dwSize - 1 );
         strcpy( &lpszBuf[dwSize - 4], "...");
      }
      else
         strcpy( lpszBuf, MessageBuffer );

      // Free the buffer allocated by the system.
      LocalFree(MessageBuffer);
   }
   return lpszBuf;
}


char * GetLastErrorText( char * lpszBuf, DWORD dwSize ) 
{
   dw_winLastError = GetLastError();
   return GetWinErrorText( lpszBuf, dwSize, dw_winLastError );
}

char * GetWinError( DWORD dwError )
{
   static char _s_winerror[264];
   return GetWinErrorText( _s_winerror, sizeof( _s_winerror), dwError );
}

#ifndef ADD_HEX_DUMP
void print_hex( char * buf, int in_size, char * msg, __int64 offset )
{
}
#else /* ADD_HEX_DUMP */
// print_hex( record_start->buffer, record_size, dbg_roffset );
#define  EndBuf(a)   ( a + strlen(a) )
#define  MY_HEX_WIDTH   16    /* out in lines of 16 characters */
void print_hex( char * buf, int in_size, char * msg, __int64 offset )
{
   static char hex_buffer[256];
   static char asc_buffer[64];
   LARGE_INTEGER li;
   int   cnt, i, c, d, off, done, ext;
   int   sz = in_size;
   char * lpd = hex_buffer;   /* for HEX values */
   char * pab = asc_buffer;   /* for ASCII values */

   li.QuadPart = offset;
   if( sz > 0 )
      fprintf( stdlis, "v5: Hex of %d bytes, from buffer %#X ... %s\n",
         sz, buf, msg );
   i = 0;
   off = 0;
   *lpd = 0;
   done = 0;
   ext = 0;
   while( sz > 0 )
   {
      if( sz > MY_HEX_WIDTH )
         cnt = MY_HEX_WIDTH;
      else
         cnt = sz;
      for( ; i < in_size; i++ )
      {
         c = buf[i];
         if(( c < ' ')||( c & 0x80 ))
            d = '.';
         else
            d = c;
         pab[off++] = (char)d;
         if( d == '%' )
            pab[off++] = (char)d;

         sprintf( EndBuf(lpd), "%02X ", (c & 0xff) );

         ext++;   /* char done */
         if( ext >= cnt ) {
            i++;     /* move on to NEXT char */
            break;   /* end of this block */
         }
      }

      pab[off] = 0;  /* zero terminate ASCII stream */
      while( ext < MY_HEX_WIDTH )
      {
         strcat(lpd, "   ");  /* fill HEX out to 16 * 3 */
         ext++;
      }
      fprintf( stdlis, "%08X%08X: %s %s %08X ([%s %d])\n",
         li.HighPart, li.LowPart,
         lpd, pab,
         (buf + done),
         msg, i );
      off = 0; /* restart ASCII offset */
      *lpd = 0;   /* restart HEX buffer */
      li.QuadPart += 16;   /* bump the OFFSET */
      sz -= cnt;  /* reduce by count */
      done += cnt;   /* and add to done count */
      ext = 0;    /* restart set counter ... */
   }  /* and loop, while sz > 0 */
   ext = 0;
}
#endif /* ADD_HEX_DUMP n/y */

char * win_get_cwd( void )
{
   static char _s_cwd[MAX_PATH];
   char * cwd = _s_cwd;
   if( _getcwd(cwd,MAX_PATH) == NULL )
      strcpy(cwd, "WARNING: _getcwd() FAILED!");
   return cwd;
}

void win_show_file_creation( char * file_name, int openflag, mode_t mode, int fd,
                            FILE * stdlis, int verbose_option )
{
#ifdef DBGV5
   if( verbose_option >= DBGV5 )
   {
      if( fd < 0 )
      {
         struct_stat st;
         if( FNSTAT(file_name, &st) == 0 )
         {
            /* file exist, so be silent, as the code will try to
               delete (unlink) this file next, unless have BIG DEBUG request */
            if( verbose_option >= 9 )   /* really HEAVY on the v's ;=)) */
            {
               fprintf( stdlis, "v9: WARNING: FAILED created file [%s] file (fd=%d) in CWD[%s]\n"
                  "due to fact that is already exists with size %I64u\n",
                  file_name, fd, win_get_cwd(), st.st_size );
            }
         }
         else
         {
            /* if the file does NOT exist, so create FAILED */
            fprintf( stdlis, "v5: WARNING: FAILED created file [%s] file (fd=%d) in CWD[%s]\n",
               file_name, fd, win_get_cwd() );
         }
      }
      else
      {
         fprintf( stdlis, "v5: Created file [%s] file (fd=%d) in CWD[%s]\n",
            file_name, fd, win_get_cwd() );
      }
   }
#endif /* DBGV5 */
}

void show_arguments(int argc, char ** argv)
{
   int   i;
   char * arg;

   program_name = "tar";

   printf( "Got %d arguments ...\n", argc );
   for( i = 0; i < argc; i++ )
   {
      arg = argv[i];
      printf("%d: [%s](%d)\n", (i + 1), arg, strlen(arg) );
   }
   printf( "Shown %d arguments ...\n", argc );
}

void win_debug_read( size_t status, int archive, char * buffer,
                    FILE * stdlis, int verbose_option )
{
#ifdef DBGV5
   if( verbose_option >= DBGV5 )
   {
      static int _s_read_cnt = 0;
      _s_read_cnt++;
      if( status >= 0 )
      {
#ifdef NEW_DELETE_FUNCTION
         extern __int64 dbg_roffset;
         fprintf( stderr, "\n%d: Read %d bytes into buffer %X, from %d fd (from off %#I64X - %#I64X)\n",
            _s_read_cnt, status, buffer, archive,
            dbg_roffset, (dbg_roffset + status) );
#ifdef HEAVY_DEBUG_DELETE
         print_hex( buffer, status, "in", dbg_roffset );
#endif /* HEAVY_DEBUG_DELETE */
         dbg_roffset += status;
#else /* !NEW_DELETE_FUNCTION */
         fprintf( stdlis, "\n%d: Read %d bytes into buffer %X, from %d fd\n",
               _s_read_cnt, status, buffer, archive );
#endif /* NEW_DELETE_FUNCTION y/n */
      }
      else
      {
#ifdef NEW_DELETE_FUNCTION
         fprintf( stdlis, "\n%d: FAILED read, from %d fd, errno = %d (from off %#I64X)\n",
            _s_read_cnt, archive, errno,
            dbg_roffset );
#else /* !NEW_DELETE_FUNCTION */
         fprintf( stdlis, "\n%d: FAILED read, from %d fd, errno = %d\n",
            _s_read_cnt, archive, errno );
#endif /* NEW_DELETE_FUNCTION y/n */
      }
   }
#endif // DBGV5
}

// eof - windebug.c
