반응형

* 마우스 드래그 방지 구현

원리

마우스 드래그 방지는 HTML/CSS/JavaScript 이벤트를 차단하는 원리입니다.

  • CSS 방식: 텍스트 선택 자체를 비활성화합니다.
  • JavaScript/HTML 이벤트 방식: 드래그 시작 이벤트(ondragstart)나 텍스트 선택 이벤트(onselectstart)를 return false로 처리합니다.

예시 코드

CSS로 구현

 
css
/* 전체 페이지 드래그 불가 */
body {
-webkit-user-select: none; /* Chrome, Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none; /* 표준 속성 */
}
 
/* 특정 영역만 드래그 허용 */
.allow-drag {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}

 HTML/JavaScript로 구현

 
xml
<body onselectstart="return false" ondragstart="return false">
<p>이 문장은 드래그할 수 없습니다.</p>
<p class="allow-drag">이 문장만 드래그 가능합니다.</p>
</body>

또는 JavaScript 코드로 이벤트 차단을 설정할 수도 있습니다:

 
javascript
document.addEventListener('dragstart', (e) => e.preventDefault());
document.addEventListener('selectstart', (e) => e.preventDefault());

 

특정 요소만 텍스트 선택 허용

원리

  • user-select: none으로 전체 페이지의 텍스트 선택을 비활성화합니다.
  • 선택을 허용할 요소에는 user-select: text를 적용합니다.

예시 코드

 
html
<style>
/* 전체 페이지 선택 금지 */
body { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
/* 특정 요소만 선택 허용 */
.select-allow { -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; }
</style>
 
<body>
<p>이 문장은 선택할 수 없습니다.</p>
<p class="select-allow">이 문장은 선택할 수 있습니다.</p>
</body>

 


마우스 우클릭 방지 구현

원리

마우스 오른쪽 클릭 시 발생하는 contextmenu 이벤트를 가로채서 preventDefault()를 호출하면, 브라우저의 기본 컨텍스트 메뉴가 표시되지 않습니다.

예시 코드

 HTML 속성 방식

 
xml
<body oncontextmenu="return false">
<p>이 페이지에서는 마우스 우클릭이 비활성화되어 있습니다.</p>
</body>

JavaScript 방식

 
javascript
document.addEventListener('contextmenu', (event) => {
event.preventDefault();
alert('이 페이지에서는 우클릭이 제한되어 있습니다.');
});

 

특정 요소만 우클릭 허용

원리

  • contextmenu 이벤트를 전체 문서에 등록하여 우클릭을 차단합니다.
  • 단, 특정 요소(event.target)가 허용 대상이면 preventDefault()를 호출하지 않습니다.

예시 코드

 
xml
<body>
<p>이 영역에서는 우클릭이 막힙니다.</p>
<div id="allowed-area" style="background:#d0f0d0; padding:15px; margin-top:10px;">
이 영역에서는 우클릭이 허용됩니다. </div>
 
<script>
const allowArea = document.getElementById('allowed-area');
document.addEventListener('contextmenu', (event) => {
// 허용 영역이 아닌 경우에만 우클릭 차단
if (!allowArea.contains(event.target))
{ event.preventDefault(); alert('이 영역에서는 우클릭이 제한되어 있습니다.'); }
});
</script>
</body>
 
*허용시킬 요소가 여러 개 인 경우...
const allowedElements = document.querySelectorAll('.right-allow');
document.addEventListener('contextmenu', (event) => {
  let allowed = false;
  allowedElements.forEach(el => {
    if (el.contains(event.target)) allowed = true;
  });
  if (!allowed) event.preventDefault();
});

이 코드는 event.target이 허용된 요소(또는 그 하위 자식)일 경우에만 우클릭이 작동하게 하며, 그 외 영역은 전부 차단됩니다.

 

💡 참고: 개발자 도구(F12)에서 JavaScript를 비활성화하거나 코드 제거로 쉽게 우회할 수 있기에, 드래그/우클릭 방지는 사용자 경험 향상용 또는 간단한 안내 수준으로만 사용하는 것이 좋습니다.


원리를 요약하면,

  • 드래그 방지: user-select:none; 또는 onselectstart/ondragstart 이벤트 차단.
  • 우클릭 방지: contextmenu 이벤트를 막아 브라우저 메뉴가 뜨지 않게 함.
반응형

build.bat

@echo off
setlocal
echo DiskFilter Driver Build Script
echo =============================

call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" 2>nul
if %ERRORLEVEL% NEQ 0 (
    call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" 2>nul
    if %ERRORLEVEL% NEQ 0 (
        call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" 2>nul
        if %ERRORLEVEL% NEQ 0 (
            echo Error: Visual Studio not found. Please install Visual Studio or run from Developer Command Prompt.
            exit /b 1
        )
    )
)

set WDKPATH=C:\Program Files (x86)\Windows Kits\10

REM Check if we're in WDK environment
if not defined WDKPATH (
    echo Error: WDK environment not detected.
    echo Please run this script from WDK Developer Command Prompt.
    echo.
    echo To open WDK Developer Command Prompt:
    echo 1. Start Menu -> Windows Driver Kit -> WDK x64 x86 Cross-Tools Command Prompt
    echo 2. Navigate to this directory
    echo 3. Run this script again
    pause
    exit /b 1
)

echo WDK environment detected: %WDKPATH%
echo.

REM Clean previous build
echo Cleaning previous build...
del *.obj *.sys *.pdb *.ilk 2>nul

REM Compile
echo Compiling diskfilter.c...
cl /c /I"%WDKPATH%\Include\10.0.26100.0\km" /I"%WDKPATH%\Include\10.0.26100.0\shared" ^
 /I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km\crt" ^
 /I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" ^
 /DDRIVER /DWIN32 /D_WIN32 /DNT /DNTDDI_VERSION=NTDDI_WIN10 /DWINVER=0x0A00 ^
 /D_WIN32_WINNT=0x0A00 /DUNICODE /D_UNICODE /DNDEBUG /Zi /Od /W3 /WX- /GS /Gy ^
 /Zc:wchar_t /Zc:forScope /Zc:inline /fp:precise /errorReport:prompt /kernel /D_AMD64_ /GS- diskfilter.c

if %errorLevel% neq 0 (
    echo Compilation failed!
    pause
    exit /b 1
)

REM Link
echo Linking diskfilter.sys...
link /DRIVER /SUBSYSTEM:NATIVE /ENTRY:DriverEntry ^
/NODEFAULTLIB /INCREMENTAL:NO /NOLOGO /DEBUG /PDB:diskfilter.pdb ^
/SUBSYSTEM:NATIVE /DRIVER:WDM /MACHINE:X64 /IGNORE:4099 /IGNORE:4210 /IGNORE:4049 /IGNORE:4103 /IGNORE:4098 ^
/LIBPATH:"%WDKPATH%\Lib\10.0.26100.0\km\x64" ^
/OUT:diskfilter.sys diskfilter.obj ntoskrnl.lib hal.lib bufferoverflowk.lib

if %errorLevel% neq 0 (
    echo Linking failed!
    pause
    exit /b 1
)

REM Check if build was successful
if exist diskfilter.sys (
    echo.
    echo Build completed successfully!
    echo Generated: diskfilter.sys
    echo.
    echo To install the driver, run: install.bat
    echo To test the driver, run: test.bat
) else (
    echo Build failed - diskfilter.sys not found!
)

echo.
echo Test completed.
endlocal
pause

 

 

 

반응형
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <windows.h>
#include <iphlpapi.h>
#include <psapi.h>
#include <tlhelp32.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

struct TcpConnection {
    std::string localAddress;
    std::string localPort;
    std::string remoteAddress;
    std::string remotePort;
    std::string state;
    DWORD pid;
    std::string processName;
};

class NetStat {
private:
    std::vector<TcpConnection> connections;

    std::string getStateString(DWORD state) {
        switch (state) {
            case MIB_TCP_STATE_CLOSED: return "CLOSED";
            case MIB_TCP_STATE_LISTEN: return "LISTENING";
            case MIB_TCP_STATE_SYN_SENT: return "SYN_SENT";
            case MIB_TCP_STATE_SYN_RCVD: return "SYN_RCVD";
            case MIB_TCP_STATE_ESTAB: return "ESTABLISHED";
            case MIB_TCP_STATE_FIN_WAIT1: return "FIN_WAIT1";
            case MIB_TCP_STATE_FIN_WAIT2: return "FIN_WAIT2";
            case MIB_TCP_STATE_CLOSE_WAIT: return "CLOSE_WAIT";
            case MIB_TCP_STATE_CLOSING: return "CLOSING";
            case MIB_TCP_STATE_LAST_ACK: return "LAST_ACK";
            case MIB_TCP_STATE_TIME_WAIT: return "TIME_WAIT";
            case MIB_TCP_STATE_DELETE_TCB: return "DELETE_TCB";
            default: return "UNKNOWN";
        }
    }

    std::string getProcessName(DWORD pid) {
        if (pid == 0) return "System";
       
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
        if (hProcess == NULL) return "Unknown";
       
        char processName[MAX_PATH];
        DWORD size = MAX_PATH;
        if (QueryFullProcessImageNameA(hProcess, 0, processName, &size)) {
            CloseHandle(hProcess);
            std::string fullPath(processName);
            size_t lastSlash = fullPath.find_last_of("\\/");
            if (lastSlash != std::string::npos) {
                return fullPath.substr(lastSlash + 1);
            }
            return fullPath;
        }
       
        CloseHandle(hProcess);
        return "Unknown";
    }

    std::string formatAddress(DWORD address) {
        struct in_addr addr;
        addr.s_addr = address;
        return std::string(inet_ntoa(addr));
    }

    std::string formatPort(DWORD port) {
        return std::to_string(ntohs((u_short)port));
    }

public:
    bool getTcpConnections() {
        DWORD size = 0;
        DWORD result = GetExtendedTcpTable(NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
       
        if (result != ERROR_INSUFFICIENT_BUFFER) {
            std::cerr << "GetExtendedTcpTable failed with error: " << result << std::endl;
            return false;
        }

        std::vector<BYTE> buffer(size);
        PMIB_TCPTABLE_OWNER_PID tcpTable = (PMIB_TCPTABLE_OWNER_PID)buffer.data();
       
        result = GetExtendedTcpTable(tcpTable, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
        if (result != NO_ERROR) {
            std::cerr << "GetExtendedTcpTable failed with error: " << result << std::endl;
            return false;
        }

        connections.clear();
        for (DWORD i = 0; i < tcpTable->dwNumEntries; i++) {
            MIB_TCPROW_OWNER_PID& row = tcpTable->table[i];
           
            TcpConnection conn;
            conn.localAddress = formatAddress(row.dwLocalAddr);
            conn.localPort = formatPort(row.dwLocalPort);
            conn.remoteAddress = formatAddress(row.dwRemoteAddr);
            conn.remotePort = formatPort(row.dwRemotePort);
            conn.state = getStateString(row.dwState);
            conn.pid = row.dwOwningPid;
            conn.processName = getProcessName(row.dwOwningPid);
           
            connections.push_back(conn);
        }
       
        return true;
    }

    void printConnections() {
        std::cout << std::left
                  << std::setw(20) << "Local Address"
                  << std::setw(10) << "Local Port"
                  << std::setw(20) << "Remote Address"
                  << std::setw(10) << "Remote Port"
                  << std::setw(15) << "State"
                  << std::setw(8) << "PID"
                  << "Process Name" << std::endl;
       
        std::cout << std::string(100, '-') << std::endl;
       
        for (const auto& conn : connections) {
            std::cout << std::left
                      << std::setw(20) << conn.localAddress
                      << std::setw(10) << conn.localPort
                      << std::setw(20) << conn.remoteAddress
                      << std::setw(10) << conn.remotePort
                      << std::setw(15) << conn.state
                      << std::setw(8) << conn.pid
                      << conn.processName << std::endl;
        }
       
        std::cout << "\nTotal TCP connections: " << connections.size() << std::endl;
    }
};

int main() {
    std::cout << "TCP Connections (IPv4)" << std::endl;
    std::cout << "======================" << std::endl << std::endl;
   
    NetStat netstat;
   
    if (!netstat.getTcpConnections()) {
        std::cerr << "Failed to get TCP connections" << std::endl;
        return 1;
    }
   
    netstat.printConnections();
   
    return 0;
}

'Develop > C&CPP' 카테고리의 다른 글

[cpp] optional  (0) 2025.04.25
[cpp] thread  (0) 2025.04.20
[cpp] atomic  (0) 2025.04.20
[cpp] mutex, lock  (0) 2025.04.20
[cpp] cpp17에서 달라진 점  (0) 2025.04.20

+ Recent posts