2016年9月28日 星期三

win32 (Partition boot record) read/write by C++

Master boot record (FOR xp/2k)
以下是 win32 console program , 用來備份 boot sector (446 bytes) , 和寫入 boot sector.
測試環境是用 vs2005 , project property 用  /MT (靜態連結,省得 RUN-TIME-DLL 版本問題)
,用 MBCS 字集.

----------------
// bootsec.cpp : /dump to backup current harddisk boot sector to hex file, /fix to restore  from hex file
//

#include "stdafx.h"

HANDLE hDevice=NULL;
unsigned char * WriteSector(int drive, DWORD startinglogicalsector, int numberofsectors,unsigned char *buffer)
{
    SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
    DWORD byteswrite=0;
    BOOL ret=WriteFile(hDevice,buffer,512*numberofsectors,&byteswrite,NULL);

    ret = FlushFileBuffers(hDevice);
    return buffer;
}
unsigned char * ReadSector(int drive, DWORD startinglogicalsector, int numberofsectors)
{
 // All msdos data structures must be packed on a 1 byte boundary
 #pragma pack (1)   
 struct
 {
    DWORD StartingSector ;
    WORD NumberOfSectors ;
    DWORD pBuffer;
 }ControlBlock;
 #pragma pack ()

 #pragma pack (1)
 typedef struct _DIOC_REGISTERS
 {
    DWORD reg_EBX;
    DWORD reg_EDX;
    DWORD reg_ECX;
    DWORD reg_EAX;
    DWORD reg_EDI;
    DWORD reg_ESI;
    DWORD reg_Flags;
 } DIOC_REGISTERS ;
 #pragma pack ()

 unsigned char* buffer = (unsigned char*)malloc (512*numberofsectors);
 DIOC_REGISTERS reg ;
 BOOL  fResult ;
 DWORD cb ;

 // Creating handle to vwin32.vxd (win 9x)
 hDevice = CreateFile ( "\\\\.\\vwin32",
         0,
         0,
         NULL,
         0,
         FILE_FLAG_DELETE_ON_CLOSE,
         NULL );

 if ( hDevice == INVALID_HANDLE_VALUE )
 {

    // win 2k code
    DWORD bytesread;
   
    // Creating a handle to drive a: using CreateFile () function ..
    char _devicename[] = "\\\\.\\A:";
    _devicename[4] += drive;
    hDevice = CreateFile(_devicename,
        // GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, 0, NULL);

    if (hDevice == INVALID_HANDLE_VALUE)
        return NULL;

    SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
    if (!ReadFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL) )
        return NULL;   
 }
 else
 {
     // code for win 95/98
     ControlBlock.StartingSector = (DWORD)startinglogicalsector;
     ControlBlock.NumberOfSectors = (DWORD)numberofsectors ;
     ControlBlock.pBuffer =  (DWORD)buffer ;

    //-----------------------------------------------------------
    // SI contains read/write mode flags
    // SI=0h for read and SI=1h for write
    // CX must be equal to ffffh for
    // int 21h's 7305h extention
    // DS:BX -> base addr of the
    // control block structure
    // DL must contain the drive number
    // (01h=A:, 02h=B: etc)
    //-----------------------------------------------------------

     reg.reg_ESI = 0x00 ;
     reg.reg_ECX = -1 ;
     reg.reg_EBX = (DWORD)(&ControlBlock);
     reg.reg_EDX = drive+1;
     reg.reg_EAX = 0x7305 ;

     //  6 == VWIN32_DIOC_DOS_DRIVEINFO
     fResult = DeviceIoControl ( hDevice,
         6,
         &(reg),
         sizeof (reg),
          &(reg),
         sizeof (reg),
         &cb,
         0);

     if (!fResult || (reg.reg_Flags & 0x0001)) return NULL;        
 }

 // CloseHandle(hDevice);
 return buffer;
}


int _tmain(int argc, _TCHAR* argv[])
{
    const int mbr_drive = 'C' - 'A';
    const int mbr_sector_start = 0;
    const int mbr_sectors = 1;
    if(argc==1)
    {
        printf("\nmbr v002");
        printf("\nmbr /dump > mbr.hex");
        printf("\nmbr /fix < mbr.hex");
        printf("\n");
    }

    unsigned char * pmbr=NULL;
    pmbr=ReadSector(mbr_drive,mbr_sector_start,mbr_sectors);
    if(pmbr==NULL)
    {
        printf("Read error\n");
        return -1;
    }

    if(argc==1)
    {
        printf("Read ok\n");       
        for(int i=0;i<16;i++)
        {
            printf("%02x ",pmbr[i]);
        }
        printf("\n");   
    }

    const int MBR_BYTES = 446;
    if(argc==2)
    {
        if(0==memcmp(argv[1],"/dump",5))
        {
            for(int i=0; i<MBR_BYTES; i++)
            {
                if (i%16==0) printf("\n");
                printf("%02x ",pmbr[i]);
            }
        }
        else if(0==memcmp(argv[1],"/fix",4))
        {
            unsigned char mbr_new[512];
            int count = 0;        // 446 hex byte expected
            const int BUF_SIZE=2048;
            char hexbuf[BUF_SIZE];
            printf("\n/fix");
            while(count<MBR_BYTES)
            {
                memset(hexbuf,0,BUF_SIZE);
                gets(hexbuf);               
                char * phex=hexbuf;
                // printf("\n[%s]",hexbuf);

                printf("\n");
                for(int i=0;i<16;i++)
                {
                    unsigned int value;
                    int item=sscanf(phex,"%02x",&value);
                    if(item!=1)
                        break;
                    phex=phex+3;
                    printf("%02x ",value);
                    mbr_new[count]=value;
                    count++;
                    if(count >= MBR_BYTES)
                        break;
                }
            }

            int diff = 0;
            for(int i=0; i<MBR_BYTES; i++)
            {
                if(mbr_new[i]!=pmbr[i]) diff++;
            }

            if(diff!=0)
            {
                for(int i=0;i<MBR_BYTES; i++) pmbr[i]=mbr_new[i];
                printf("\nneed write new mbr 446 bytes record into harddisk\n");
                WriteSector(mbr_drive,mbr_sector_start,mbr_sectors,pmbr);
            }
        }
    }

    printf("\n");
    if(hDevice!=NULL)
        CloseHandle(hDevice);
    if(pmbr)
        free(pmbr);
    return 0;
}

標籤: , , ,

2016年9月25日 星期日

vc2010 express install in xpsp3 failure

   You must install dot.net 2 first.

標籤:

2016年9月21日 星期三

用function call operator 來作getter 和 setter

我的結論是目前不推薦使用.

code 如----以下所示

網上有人大推這種 get/set 方法. 認為其不用 .getxxx() , .setxxx(...)
或許小程式有其優雅,

缺點是無法簡單的用 regular/expression 來搜尋其get/set 的引用.
但是一個 regular/expression 無法搜尋引用的寫法,表示人在閱讀,推敲其 code 時,
也要增加額外的負擔, 記住 (以下的code為例) class 產生出來的 instance 名子,才能追其code.

.要靠 compiler 級別的editor 才能找出其引用.
-------------------------------
class cInt {
    int v;
public:
    cInt() : v(0) {}

    int operator ()()                // cInt value get-function
    {
        return v;
    }

    void operator ()(int new_v)        // cInt value set-funciton
    {
        v = new_v;
    }

    void dump(){
        Output("cInt'v=%d\n",v);
    }
};

void test_paren_operator()
{
    cInt ci;
    ci.dump();
    // int v1=ci.v;    // not public
    int v2=ci();    // get

    ci(3);            // set
    ci.dump();
    // ci() = 4;    // not l-value
    ci.dump();
}
--------------

cInt'v=0
cInt'v=3
cInt'v=3

標籤: , , ,

c++ set/get data member 用 set() template 區分出來

以下是將 class 的data member 基本上給外部用的,用 const
如果是 讀取,當然沒問題,
但是如果是設定新值, 就必需要用 set member function, 或 set template
如果 data member 繁多, 就用 set template 吧, 省得寫一大堆沒營養的 fuction.

這樣作的好處是 trace code 的時候, 可以很容易的找到 set value 的地方.
當然如果不這麼作,用眼看,也是分析的出來. 但是
讀取通常有數十個到數百個 reference, 設定通常是數個.
要在數百個中找到數個,也是很累人的.
------------------------------------
#include <iostream>
#include <wtypes.h>
using namespace std;

void Output(const char* szFormat, ...)
{
    char szBuff[1024];
    va_list arg;
    va_start(arg, szFormat);
    _vsnprintf(szBuff, sizeof(szBuff), szFormat, arg);
    va_end(arg);

    OutputDebugString(szBuff);
}


template <class T>
T & set(const T& vin) {
    return (T&) vin;
}

class cOne {
public:
    const int v;
    // int v;

    cOne() : v(0)
    {}

    void dump()
    {
        Output("cOne'v = %d\n",v);
    }
};


void func_modify(int & var)
{
    var++;
}

void set_test()
{
    cOne c1;
    c1.dump();

//    c1.v = 7;            // error
    int v1 = c1.v;       

//    int &v2 = c1.v;        // error
    int &v3 = set(c1.v);
    v3=4;
    c1.dump();

    set(c1.v) = 6;    c1.dump();
//    func_modify(c1.v);        // error
    func_modify(set(c1.v));    c1.dump();

    cOne *pc1 = new cOne;
//    pc1->v = 10;            // error
//    int& v4 = pc1->v;        // error
    int& v5 = set(pc1->v);
    v5=11;
    pc1->dump();

    set(pc1->v) = 12;    pc1->dump();
//    func_modify(pc1->v);    // error
    func_modify(set(pc1->v)); pc1->dump();
    delete pc1;
}

int main()
{
  cout << "Hi set_test" << endl;
  set_test();
  // getchar();
}
--------------------
----- Output -----
cOne'v = 0
cOne'v = 4
cOne'v = 6
cOne'v = 7
cOne'v = 11
cOne'v = 12
cOne'v = 13

標籤: , ,

2016年9月14日 星期三

use vs2005 commanline compile , don't install , but copy.

當你安裝好 vs2005 , 可以把安裝目錄備份(例如c:\VS8),
可以在(c:\vs8\vc\) vcvarsall.bat 頭一行加
SET VS80COMNTOOLS=C:\VS8\Common7\Tools\
然後再備份.

以後新裝 os,如果只想調用 commandline compile code, 可以不用安裝 .net2 vs.. long time
把之前的備份copy 回原位 (例如 c:\VS8)
如有需要請安裝 (vcredist_x86_vc2005sp1.exe)
如有(ml.exe from vs2008express) , 請安裝(vcredist_x86_vc2008sp1.exe)

 
進command prompt , cd到 c:\vs8\vc\
只要打 vcvarsall.bat 即有 commandline compile 的能力.

標籤: ,

Using vs2005 +ml(2008express) build 7-zip 16.02

vm xpsp2
+我用 vs2005(安裝vc(.net2)(no mobile) 約 1G   
+vs2008sp1(ml.exe)  可以直接用 7-zip 打開壓縮(Ixpvc.exe)(vs_setup.cab)複製 
          FL_ml_exe_19621_x86_ln.3643236F_FC70_11D3_A536_0090278A1BB8
          vcredist_x86_vc2008sp1.exe (必需要安裝)
    用 2008ex 的 ml.exe 取代 2005 的 ml.exe
+7-zip 9.22 src  compile 方法同下
+7-zip 16.02 src 解開後  用 vs2005 command prompt  到 C:\c\7zsrc\CPP\7zip  打 nmake
    即可得 7z.exe 7-zip.dll 7z.dll 7zFM.exe 7zG(n).exe
    打 7zFM 和 7zG 時會出現要連(MSVCR80.DLL)
    用 vs2005 打開 CPP\7zip\UI\GUI\ 的 dsw (build releaseU)  --> 7zGn.exe
    CPP\7zip\UI\FileManager\ 的 dsw (build releaseU) --> 7zFM.exe
    即不會出現要求要連 msvcr80.dll 的問題
+7zip 16.02 src  到 c:\c\7zsrc\cpp\7zip 打 nmake MY_STATIC_LINK=1
    即不會出現要求要連 msvcr80.dll 的問題.

標籤: , , ,

2016年9月10日 星期六

build TTSAPP(MS Speech SDK 5.1) with Unicode

predefine symbol:
remove:   _MBCS 
add:        _UNICODE,UNICODE
## must add both _UNICODE and UNICODE , just one don't work.
environment: VC6, SpeechSDK51.exe
PS:  universal string process  code snip
            // #include <stdio.h>
            // #include <TCHAR.H>
            {
                static int g_count = 0;
                HWND htWnd = GetDlgItem(m_hWnd, IDC_STATIC_RATE);
                if ( htWnd )
                {
                    TCHAR buf[256];
                    _stprintf(buf,_T("Rate %d "),g_count);

                    SetWindowText(htWnd, buf );
                    g_count ++;
                }
            }

    

標籤: , , , ,