출력

C:\ Total : 20002 MByte  Free : 1225 MByte
D:\ Total : 132614 MByte         Free : 26944 MByte
E:\ Total : 61443 MByte  Free : 61373 MByte
F:\ Total : 171898 MByte         Free : 156790 MByte
G:\ Total : 5130 MByte   Free : 3876 MByte
                http://fehead.tistory.com


소스

#include <windows.h>
#include <iostream>
#include <direct.h>

using namespace std;

struct ST_HDDUsage
{
    unsigned long   total;          // MByte
    unsigned long   free;           // MByte
};

class HddUsage
{
    typedef BOOL (WINAPI *GET_DISK_FREE_SPACE_EX)(
        LPCTSTR, PULARGE_INTEGER,
        PULARGE_INTEGER, PULARGE_INTEGER);

private:
    HINSTANCE       m_hInstLib;
    GET_DISK_FREE_SPACE_EX  m_pGetDiskFreeSpaceEx;

public:
    HddUsage()      :       m_hInstLib( 0 ), m_pGetDiskFreeSpaceEx( 0 )     {}
    ~HddUsage()             {       destroy();      }

    bool    init()
    {
        m_hInstLib = LoadLibrary( "kernel32.dll" );
        if( m_hInstLib == 0 )
            return false;

        m_pGetDiskFreeSpaceEx = reinterpret_cast<GET_DISK_FREE_SPACE_EX>(
            GetProcAddress( m_hInstLib, "GetDiskFreeSpaceExA") );

        if( m_pGetDiskFreeSpaceEx == 0 )
            return false;

        return true;
    }

    void destroy()
    {
        if( m_hInstLib )
            FreeLibrary( m_hInstLib);
        m_hInstLib = 0;
    }

    bool GetDiskUsage( const char * pszDrive, ST_HDDUsage * pHddUsage )
    {
        unsigned __int64 i64FreeBytesToCaller = 0;
        unsigned __int64 i64TotalBytes = 0;
        unsigned __int64 i64FreeBytes = 0;

        BOOL ret = m_pGetDiskFreeSpaceEx( pszDrive,
            reinterpret_cast<PULARGE_INTEGER>( &i64FreeBytesToCaller ),
            reinterpret_cast<PULARGE_INTEGER>( &i64TotalBytes ),
            reinterpret_cast<PULARGE_INTEGER>( &i64FreeBytes ) );
        if( !ret )
            return false;

        pHddUsage->total = static_cast<unsigned long >(
            i64TotalBytes / (1024*1024) );          // Hdd total (MByte)

        pHddUsage->free = static_cast<unsigned long >(
            i64FreeBytes / (1024*1024) );           // Hdd Free (MByte)

        return true;
    }

};

int main(int, char *[])
{
    HddUsage        hddUsage;
    if( hddUsage.init() ) {
      
        // 있는 하드 디스크만 출력.
        char    driveName[4] = "A:\\";
        for( ULONG uDriveMask = _getdrives() ; uDriveMask ; uDriveMask >>= 1 )
        {
            if( uDriveMask & 1 )
            {
                // 하드 디스크일때만 출력.
                if( GetDriveType( driveName ) == DRIVE_FIXED ) {
                    ST_HDDUsage     hdd;
                    if( hddUsage.GetDiskUsage( driveName, &hdd ) ) {
                        cout << driveName << " Total : " << hdd.total <<
                            " MByte\t Free : " << hdd.free << " MByte\n";
                    }
                }
            }
            ++driveName[0];         // 드라이브명 변경. A:\, B:\ ~~~Z:\~~
        }
    }
    cout << "\t\thttp://fehead.tistory.com\n";
    return 0;
}

부끄럽지만 거의 배꼈습니다. ㅡ.ㅡ

일단 간단하게 zip파일(여러 파일이 압축된것) 압축을 풀수 있습니다.
단순버전
// 압축 파일을 해제 한다.
bool ExtractZip( const string & zipFile, const string & dstPath )
{
    // Zip파일 오픈
    unzFile uf = unzOpen( zipFile.c_str() );

    // 첫번째 Zip목록으로 이동
    int ret = unzGoToFirstFile(uf);

    for(;;)
        {
                unz_file_info   file_info;

                // 압축된 파일명을 얻음.
                char fileName[MAX_PATH];
                ret = unzGetCurrentFileInfo( uf, &file_info, fileName, sizeof(fileName), NULL, 0, NULL, 0 );

                // 압축된 파일 하나를 연다.
                ret = unzOpenCurrentFile( uf );

                // 폴더 만들기.
                MkPath( targetFilename );

                // 파일로 쓰기.
                ofstream    ofs( targetFilename.c_str() );

                // 압축을 푼다.
                char buf[4096];
                for(;;)
                {
                        int len = unzReadCurrentFile( uf, buf, sizeof(buf) );
                        if( len == 0 )
                                break;
                        ofs.write( buf, len );
                }
                ofs.close();

                unzCloseCurrentFile( uf );

                ret = unzGoToNextFile( uf );
        }

        if(ret==UNZ_END_OF_LIST_OF_FILE)
                break;

        unzCloseCurrentFile(uf);

        unzClose(uf);

    return true;
}


전체버전
// 작성자 : fehead.tistory.com
//
// 사용법 : lunzip.exe 압축파일 압축풀디렉토리
//    예제) lunzip.exe c:\test.zip c:\tmp\test
//
// 빌드 환경 : visual c++ 2003, 2008
//
// 참고자료 : zipj03.7z http://www.kippler.com/win/zipj/
//            minizip http://www.winimage.com/zLibDll/minizip.html

#include < iostream >
#include < string >
#include < Windows.h >
#include < direct.h >
#include < fstream >
#include "unzip/unzip.h"

using namespace std;

bool ExtractZip( const string & zipFile, const string & dstPath );  // 압축파일을 해당 디렉토리에 푼다.
bool IsDirectory( const string & path );                            // 디렉토리인지 확인
bool MkPath( const string & fullPath );                             // 해당 디렉토리를 만듬.

// 메인 함수
int main( int argc, char * argv[] )
{
    if( argc != 3 )
    {
        cout << "사용법 : lunzip.exe 압축파일 압축풀디렉토리\n";
        return 0;
    }

    ExtractZip( argv[1], argv[2] );

    //ExtractZip( "d:\\test.zip", "d:\\tmp\\test" );
    return 0;
}

// 디렉토리인지 알아냄.
bool IsDirectory( const string & path )
{
    DWORD ret = GetFileAttributes( path.c_str() );
    
    if( ret == 0xffffffff)
        return false;

    if( ret & FILE_ATTRIBUTE_DIRECTORY )
        return true;

    return false;
}

// 디렉토리를 만든다.
bool MkPath( const string & fullPath )
{
    string  path = fullPath;

    // 파일경로에서 디렉토리 경로만 얻음.
    string::size_type pos = path.find_last_of( "/\\" );
    if( pos != string::npos )
    {
        path.erase( ++pos, string::npos );
    }

    // 네트워크 경로 인가? 예제) "\\192.168.0.1\test"
    pos = 0;
    if( path.compare( 0, 2, "\\\\") == 0 )
        pos = 2;

    // 상위 경로를 찾아가며 디렉토리를 순서대로 만든다.
    while( (pos = path.find_first_of( "/\\", pos )) != string::npos )
    {
        string subPath = path.substr( 0, pos++ );
        
        if(IsDirectory( subPath )==false)
            _mkdir( subPath.c_str() );
    }

    return IsDirectory( fullPath );
}

// 압축 파일을 해제 한다.
bool ExtractZip( const string & zipFile, const string & dstPath )
{
    // Zip파일 오픈
    unzFile uf = unzOpen( zipFile.c_str() );
    if( uf == 0 )
        return false;

    // 첫번째 Zip목록으로 이동
    int ret = unzGoToFirstFile(uf);

    if( ret != UNZ_OK )
        goto END;

    for(;;)
    {
        unz_file_info   file_info;
        
        // 압축된 파일명을 얻음.
        char fileName[MAX_PATH];
        ret = unzGetCurrentFileInfo( uf, &file_info, fileName, sizeof(fileName), NULL, 0, NULL, 0 );

        if( ret != UNZ_OK )
            goto END;

        // 압축된 파일 하나를 연다.
        ret = unzOpenCurrentFile( uf );
        if ( ret != UNZ_OK )
        {
            cerr << fileName << " 파일 열기 실패\n";
            break;
        }

        // TargetFilename = destPath + "\\" + "압축 풀려는 파일명"
        string targetFilename = dstPath;
        if( *targetFilename.rbegin()  != '\\' )
            targetFilename.append( "\\" );
        targetFilename.append( fileName );

        // 폴더 만들기.
        MkPath( targetFilename );

        if( IsDirectory( targetFilename ) == false )
        {
            // 파일로 쓰기.
            ofstream    ofs( targetFilename.c_str() );
            if( !ofs )
            {
                cerr << "파일 열기 실패:" << targetFilename << endl;
                break;
            }
            cout << targetFilename << " : " << file_info.uncompressed_size << "bytes\n";

            // 압축을 푼다.
            char buf[4096];
            for(;;)
            {
                int len = unzReadCurrentFile( uf, buf, sizeof(buf) );
                if( len < 0 )  
                    goto END;
                if( len == 0 )
                    break;

                ofs.write( buf, len );
            }
            ofs.close();
        }

        unzCloseCurrentFile( uf );

        ret = unzGoToNextFile( uf );

        if(ret==UNZ_END_OF_LIST_OF_FILE)
            break;
    }

END:
    if(uf)
        unzCloseCurrentFile(uf);

    if(uf)
        unzClose(uf);

    return true;
}



참고사이트
  zipj 0.3
  minizip

소스 및 실행파일
 Visual C++ 2003, 2008환경에서 개발하였습니다.
 Visual C++ 2003에서는 디버그 모드에서만 작동하더군요.( std::string 문제 발생 )





  1. 환경
    1. 가) 개발PC : Visual C++ 2008이 설치 되어있고 소스가 있는 PC.
    2. 나) PC (IP : 192.168.x.x ) : 디버깅할 프로그램이 돌아가고 있는 PC.
    3. 소스 컴파일은 Relese모드 그리고 디버그 정보 생성 옵션이 들어가 있다



  1. 나)PC에 Remote Debugging Monitor 복사(설치)
    1. 나) PC에 가)개발PC에 있는 %Program Files%\Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger\x86 디렉토리를 복사.
      1. 나) PC    D:\Remote_Monitor 디렉토리로 복사했다고 가정.


  2. 나) PC에서 msvsmon.exe 실행

  3. 나) PC에서 msvsmon.exe 옵션 바꾸기.
    1. Tools--> Options 클릭
    2. No Authentication 선택, Allow any user to debug 선택후 적용.



  4. 나)PC에서 디버깅할 프로그램 실행

  5. 가)개발PC에 있는 Visual C++ 실행후 해당 소스 열기
    1. Release 모드 선택

  6. 가)개발PC Visual c++ 리모드 디버깅 시작
    1. VisualC++ Menu --> Tools --> Attach to Process 선택.


  7. 이제 디버깅이 시작되었습니다.

링크 : http://fehead.tistory.com/89
strcpy_s의 두번째 인자에 _TRUNCATE가 들어가면 어떤 현상이 일어날까?

_TRUNCATE의 값은 unsigned int의 최대값 즉 약42억(정확히 42 9496 7295) - 4G - 값이므로 무한대라고 할수 있다.

strcpy_s( a, _TRUNCATE, b) --> strcpy_s( a, 42억, b)..

결론은 strcpy_s를 strcpy로 바꿔버리는 현상(첫번째 인자 버퍼는 보호하지 않음)이 일어난다.
예제 소스
#include <string.h>
#include <iostream>

using namespace std;

int main( int, char *[] )
{
    char    c[16];
    char    a[4];
    
    const char *  b = "012345678901234567890";

    cout << "\n====== memset ======\n";

    memset( a, 'A', sizeof(a) );
    memset( c, 'C', sizeof(c) );

    cout.write( a, _countof(a) ) << endl; // AAAA 출력
    cout.write( c, _countof(c) ) << endl; // CCCCCCCCCCCCCCCC 출력

    /* 예외 발생
    strcpy_s( a, _countof(a), b );
    cout.write( a, _countof(a) ) << endl;
    cout.write( c, _countof(c) ) << endl;
    */ 
    
    cout << "\n====== strcpy_s ======\n";
    strcpy_s( a, _TRUNCATE, b );
    cout.write( a, _countof(a) ) << endl; // 0123 출력
    cout.write( c, _countof(c) ) << endl; // buffer Overflow

    return 0;
}


출력

====== memset ======
AAAA
CCCCCCCCCCCCCCCC

====== strcpy_s ======
0123
234567890    -----> over flow

뱀다리) _TRUNCATE 의 값은 #define _TRUNCATE ((size_t)-1) 이다
그리고 size_t는 unsigned int 형이므로 _TRUNCATE 값은 unsigned int 의 최대값 대략 42억(정확히 42 9496 7295)의 값을 가집니다.
Visual C++에서 작업 하였다.

출력
CPU Usage : 57.8125%
CPU Usage : 40.625%
CPU Usage : 28.125%
CPU Usage : 29.6875%
CPU Usage : 18.1818%
CPU Usage : 21.875%
CPU Usage : 4.6875%
CPU Usage : 1.5625%


소스
#pragma comment(lib, "pdh.lib")

#include <windows.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>

using namespace std;

class CpuUsage
{
private:
        PDH_HQUERY              m_hQuery;
        PDH_HCOUNTER    m_hCounter;

public:
        CpuUsage()      :       m_hQuery( 0 ), m_hCounter( 0 )  {}
        ~CpuUsage()             {       destroy();      }

        bool    init()
        {
                PDH_STATUS      status = PdhOpenQuery (0, 0, &m_hQuery);

                if( status != ERROR_SUCCESS )
                        return false;

                status = PdhAddCounter( m_hQuery, "\\Processor(_TOTAL)\\% Processor Time", 0, &m_hCounter );

                if( status != ERROR_SUCCESS )
                        return false;

                status = PdhCollectQueryData( m_hQuery );

                if( status != ERROR_SUCCESS )
                {
                        return false;
                }

                return true;
        }

        void    destroy()
        {
                if( m_hQuery )
                        PdhCloseQuery( m_hQuery );
                m_hQuery = 0;
        }

        bool    getCpuUsage( double * val )
        {
                PDH_STATUS      status = PdhCollectQueryData( m_hQuery );

                if( status != ERROR_SUCCESS )
                        return false;

                PDH_FMT_COUNTERVALUE    value;

                status = PdhGetFormattedCounterValue( m_hCounter, PDH_FMT_DOUBLE,       0, &value);

                if (status != ERROR_SUCCESS)
                        return false;
                *val = value.doubleValue;
                return true;
        }

};


int main( int argc, char * argv[] )
{
        CpuUsage        cpuUsage;
        if( cpuUsage.init() == false )
                return 1;

        while( true )
        {
                double  val = 0.0;
                if( cpuUsage.getCpuUsage( &val ) )
                        cout << "CPU Usage : " << val << "%\n";
                Sleep( 500 );
        }
        cout << "\t\thttp://fehead.tistory.com\n";

        return 0;
}


출력
 
Total : 2096236 free : 1242116


소스
#include <Windows.h>
#include <iostream>

struct ST_MemLog
{
        ULONG   totalMem;
        ULONG   freeMem;
};


bool    getMemLog( ST_MemLog * pMemLog )
{
        static const long       KBYTE = 1024;

        MEMORYSTATUSEX statex;

        statex.dwLength = sizeof (statex);

        if( GlobalMemoryStatusEx( &statex ) == FALSE )
                return false;

        // total Kbytes of physical memory
        pMemLog->totalMem = static_cast<ULONG>( statex.ullTotalPhys / KBYTE );

        // free Kbytes of physical memory.
        pMemLog->freeMem = static_cast<ULONG>( statex.ullAvailPhys / KBYTE );

        return true;
}

int main( int argc, char * argv[] )
{
        ST_MemLog       memLog;

        if( getMemLog( &memLog ) ) {
                cout << "Total : " << memLog.totalMem <<
                        "\tfree : " << memLog.freeMem << endl;
        }
        cout << "\t\thttp://fehead.tistory.com\n";

        return 0;
}


소스예제
#include <windows.h>
#include <iostream>

using namespace std;

int main( int, char *[] )
{
        const int arr[] = {100, 200, 300, 400, 500};

        cout << "_countof(arr)              : " << _countof(arr) << endl;
        cout << "sizeof(arr)                : " << sizeof(arr) << endl;
        cout << "sizeof(arr)/sizeof(arr[0]) : " << sizeof(arr) / sizeof(arr[0]) << endl;

        return 0;
}

결과
_countof(arr)              : 5
sizeof(arr)                : 20
sizeof(arr)/sizeof(arr[0]) : 5


소스를 참고 하시라^^

소스 세이프 2005에서 쓰기 모드로 코딩하기 무척이나 힘듭니다.

쓰기모드로 컴파일도 제대로 못하게 해놔서 참 힘들더군요.

파일 하나를 다른사람이 체크아웃하고 사용중이면 거의 아무것도 못하게 되어있습니다.


그래서 열심히 구글링 해봤으나 못 찾고 결국 하나하나 해서 결국 찾았습니다.


Visual C++ 2008 옵션창에 들어가서



  • 툴--> 옵션

    • 소스제어(Source Control) --> 환경(Environment) 중

      • On Edit --> 단독 체크 아웃 확인(Prompt for exclusive checkouts)

으로 설정하시고 visual C++ 재시작하시고 쓰기 모드로 작업하시면 되겠습니다.


기존에 쓰기 모드로 한 작업들은 위설정으로 바꾸고 GetLast후 다시 작업하셔야 합니다.

http://msdn.microsoft.com/en-us/library/c785s0kz(VS.80).aspx

변수값 출력
> ? var1

변수값 출력시 ? 붙이기 귀찮을때
> immed
명령어를 치고 변수값을 직접 넣어 값을 출력한다.

command window로 복귀
>cmd

header 파일에 아래의 내용을 넣고 컴파일한다.

#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")

참고 링크
http://kldp.org/node/105369


+ Recent posts