这节课主要是复习之前的内容,查缺补漏
TLS
线程局部存储(Thread Local Storage,TLS),是一种变量的存储方法,这个变量在它所在的线程内是全局可访问的,但是不能被其他线程访问到,这样就保持了数据的线程独立性。而熟知的全局变量,是所有线程都可以访问的,这样就不可避免需要锁来控制,增加了控制成本和代码复杂度。
新建控制台应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#include <windows.h> #include <iostream> using namespace std;
DWORD WINAPI ThreadFunc(LPVOID lpParam) { DWORD dw = (DWORD)TlsGetValue(0); TlsSetValue(0, (LPVOID)0x44557788); return 0; } int main() { TlsSetValue(0, (LPVOID)0x123456); DWORD dw = (DWORD)TlsGetValue(0); DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; char szMsg[80]; hThread = CreateThread( NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId ); WaitForSingleObject(hThread, INFINITE); dw = (DWORD)TlsGetValue(0); return 0; }
|
dw的值为0x123456
运行过ThreadFunc函数后dw的值仍为0x123456
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include <windows.h> #include <iostream> using namespace std;
void FuncC() { DWORD dw = (DWORD)TlsGetValue(0); printf("FuncC tid:%d \t dw:%d\r\n", GetCurrentThreadId(), dw); }
void FuncB() { DWORD dw = (DWORD)TlsGetValue(0); FuncC(); printf("FuncB tid:%d \t dw:%d\r\n", GetCurrentThreadId(), dw); }
void FuncA() { DWORD dw = (DWORD)TlsGetValue(0); FuncB(); printf("FuncA tid:%d \t dw:%d\r\n", GetCurrentThreadId(), dw); }
DWORD WINAPI ThreadFunc(LPVOID lpParam) { DWORD dwTest = 0x11223344; FuncA(); DWORD dw = (DWORD)TlsGetValue(0); TlsSetValue(0, (LPVOID)dwTest); return 0; } int main() { TlsSetValue(0, (LPVOID)0x123456); DWORD dw = (DWORD)TlsGetValue(0);
DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; char szMsg[80]; hThread = CreateThread( NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId ); WaitForSingleObject(hThread, INFINITE); dw = (DWORD)TlsGetValue(0); return 0; }
|
高低位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| LARGE_INTEGER li; DWORD dwLow = 0x12345678; DWORD dwHi = 0x77778888; __int64 nVal = 0x7777888812345678;
union MyUnion//共用体,lh和m_n { struct { DWORD dwLow; DWORD dwHi; }lh; __int64 m_n; }; MyUnion u; u.lh.dwLow = dwLow; u.lh.dwHi = dwHi;
|
运行结果
修改文件权限
GetFileAttributes
为一个指定的文件或目录返回文件系统的属性。可以使用GetFileAttributesEx 函数获得更多的属性信息。如果要实现交互式操作,可以使用GetFileAttributesTransacted 函数。
参数
lpFileName [in]*文件或目录的名字,对于ANSI版本,名字不能大于MAX_PATH。
返回值
如果函数成功,返回值包含文件或目录的属性。如果函数失败,返回值是INVALID_FILE_ATTRIBUTES。
备注
当该函数作用在一个挂载文件夹时,它返回目录的文件系统的属性,而不是根目录的信息。为了获得与文件属性关联的卷信息,可以调用GetVolumeNameForVolumeMountPoint 函数。
SetFileAttributes
参数:lpFileName:输入参数,为需要设置文件属性的文件或目录。返回值:返回BOOL值,表示是否成功。
使用说明:文件系统中对文件属性的表示使用了DWORD类型的数据,多个文件属性用“|”运算连在一起
总结
设置文件属性: SetFileAttributes(文件名, 属性值)
读取文件属性:GetFileAttributes(文件名)
读取文件属性
SetFileAttributes(文件名, FILE_ATTRIBUTE_READONLY); // 设定为只读
SetFileAttributes(文件名, FILE_ATTRIBUTE_HIDDEN ); //设定为隐藏
SetFileAttributes(文件名, FILE_ATTRIBUTE_SYSTEM); //设定为系统
SetFileAttributes(文件名, FILE_ATTRIBUTE_ARCHIVE); //设定为保存
SetFileAttributes(文件名, FILE_ATTRIBUTE_NORMAL); //设定为一般 (取消前四种属性)
设定二种以上的属性:
设定为只读 + 隐藏
SetFileAttributes(文件名, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN)
设定为只读 + 隐藏 + 系统 + 保存
SetFileAttributes(文件名, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)
取消所有设定
SetFileAttributes(文件名, FILE_ATTRIBUTE_NORMAL)
要读取文件目前的属性,则是用 GetFileAttributes:
GetFileAttributes(文件名)
返回值与文件属性的宏定义相比,如返回1,表示FILE_ATTRIBUTE_READONLY
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include <windows.h> #include <iostream> using namespace std;
BOOL GetSeDebugPrivilegeState(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege, BOOL *bPrivilegeState=(BOOL *)0) { LUID luid; BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid); if (!bRet) { return FALSE; }
_TOKEN_PRIVILEGES tp; _TOKEN_PRIVILEGES tpOld{}; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL ); if (!bRet) { return FALSE; } if (bPrivilegeState != NULL) { *bPrivilegeState = tpOld.Privileges[0].Attributes; } return TRUE; } int main() { HANDLE hToken; OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken); GetSeDebugPrivilegeState(hToken, "SeBackPrivilege", TRUE); GetSeDebugPrivilegeState(hToken, "SeRestorePrivilege", TRUE);
DWORD dwAttr = GetFileAttributes("C:\\Windows\\Media"); DWORD dwNew = dwAttr ^ FILE_ATTRIBUTE_READONLY; BOOL bRet = SetFileAttributes("C:\\Windows\\Media", dwNew); HANDLE hFile = CreateFile("C:\\Windows\\Media\\Alarm01.wav", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { return 0; } SetFilePointer(hFile, 0, NULL, FILE_END); DWORD dw = 0x12345678; bRet = WriteFile(hFile, &dw, sizeof(dw), NULL, NULL); CloseHandle(hFile); return 0; }
|
成功修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include <windows.h> #include <iostream> using namespace std;
BOOL GetSeDebugPrivilegeState(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege, BOOL *bPrivilegeState=(BOOL *)0) { LUID luid; BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid); if (!bRet) { return FALSE; }
_TOKEN_PRIVILEGES tp; _TOKEN_PRIVILEGES tpOld{}; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL ); if (!bRet) { return FALSE; } if (bPrivilegeState != NULL) { *bPrivilegeState = tpOld.Privileges[0].Attributes; } return TRUE; } int main() { HANDLE hToken; OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken); GetSeDebugPrivilegeState(hToken, "SeBackPrivilege", TRUE); GetSeDebugPrivilegeState(hToken, "SeRestorePrivilege", TRUE);
HANDLE hFile = CreateFile("C:\\Windows\\Media\\Alarm01.wav", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { return 0; } SetFilePointer(hFile, 0, NULL, FILE_END); DWORD dw = 0x12345678; BOOL bRet = WriteFile(hFile, &dw, sizeof(dw), NULL, NULL); CloseHandle(hFile); return 0; }
|
恢复成原来的样子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
#include <windows.h> #include <iostream> using namespace std;
BOOL GetSeDebugPrivilegeState(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege, BOOL *bPrivilegeState=(BOOL *)0) { LUID luid; BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid); if (!bRet) { return FALSE; }
_TOKEN_PRIVILEGES tp; _TOKEN_PRIVILEGES tpOld{}; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL ); if (!bRet) { return FALSE; } if (bPrivilegeState != NULL) { *bPrivilegeState = tpOld.Privileges[0].Attributes; } return TRUE; } int main() { HANDLE hToken; OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken); GetSeDebugPrivilegeState(hToken, "SeBackPrivilege", TRUE); GetSeDebugPrivilegeState(hToken, "SeRestorePrivilege", TRUE);
HANDLE hFile = CreateFile("C:\\Windows\\Media\\Alarm01.wav", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { return 0; } SetFilePointer(hFile, -8, NULL, FILE_END); SetEndOfFile(hFile); CloseHandle(hFile); return 0; }
|