概述:Windows 管道创建与使用

[toc]

管道类

.h

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
#pragma once

#include <stdio.h>
#include <tchar.h>

#include <iostream>
#include <Windows.h>
#include <string>
#include <thread>
#include <memory>

#define TIME_ASECOND 1000

enum PIPEUSERTYPE {
USER_CLIENT, //客户端
USER_SERVER, //服务端
};

class PipeIPC {
public:
explicit PipeIPC(PIPEUSERTYPE role) :m_Role(role), m_hPipeHandle(INVALID_HANDLE_VALUE) {};
~PipeIPC();

bool WriteData(__in const std::string& datas); //写入数据
void Release();
bool ReadData(__out std::string& datas, __out bool bIsPipeEnd); //读取数据
bool InitPipeIPC(); //初始化管道通信

bool IsInit();

BOOL InitSecurityAttributes();

void Connect();
void DisConnect();
private:
PIPEUSERTYPE m_Role;
HANDLE m_hPipeHandle;
SECURITY_ATTRIBUTES m_sec_attr; //security attributes
};

.cpp

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include "PipeIPC.h"
#include <AccCtrl.h>
#include <AclAPI.h>

using namespace std;

#define PIPE_SERVER_NAME "\\\\.\\pipe\\TrustAgent\\pipe.ToFixService"
#define PIPE_CLIENT_NAME "\\\\.\\pipe\\TrustAgent\\pipe.ToTrustAgent"

PipeIPC::~PipeIPC()
{
if (m_hPipeHandle != INVALID_HANDLE_VALUE)
{
DisconnectNamedPipe(m_hPipeHandle);
CloseHandle(m_hPipeHandle);
}
}

bool PipeIPC::InitPipeIPC()
{
if (USER_SERVER == m_Role && nullptr != m_hPipeHandle)
{
InitSecurityAttributes();
// cout << "ser" << endl;
m_hPipeHandle = CreateNamedPipeA(PIPE_SERVER_NAME, PIPE_ACCESS_DUPLEX, //双向模式
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE/* | PIPE_NOWAIT*/,
PIPE_UNLIMITED_INSTANCES,//设置最大容纳实例数目
0,
0,
NULL, (LPSECURITY_ATTRIBUTES)&m_sec_attr);
//如果管道创建失败
if (m_hPipeHandle == INVALID_HANDLE_VALUE)
{
return false;
}

#if 0
if (!ConnectNamedPipe(m_hPipeHandle, nullptr)) {
cout << "ConnectNamedPipe failed" << endl;
return false;
}
#endif
}
else
{
if (WaitNamedPipeA(PIPE_CLIENT_NAME, TIME_ASECOND * 5) == FALSE)
return 0;

m_hPipeHandle = CreateFileA(
PIPE_CLIENT_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

//如果管道创建失败
if (m_hPipeHandle == INVALID_HANDLE_VALUE)
{
return false;
}

WriteData("[PIPE] ------ V10 Init ------");
}

return true;
}

bool PipeIPC::IsInit()
{
return m_hPipeHandle == INVALID_HANDLE_VALUE ? false : true;
}

/*
[details] 创建管道去管理员权限
*/
BOOL PipeIPC::InitSecurityAttributes()
{
PSID pEveryoneSID = NULL;
PACL pACL = NULL;
EXPLICIT_ACCESS ea;
PSECURITY_DESCRIPTOR pSD = NULL;
void* ea_addr = NULL;
void* acl_addr = NULL;
void* sd_addr = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;

if (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
{
return FALSE;
}
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = (LPTSTR)pEveryoneSID;
ea_addr = &ea;
if (ERROR_SUCCESS != SetEntriesInAcl(1, &ea, NULL, &pACL))
{
goto cleanup;
}
acl_addr = &pACL;
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
goto cleanup;
}
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
goto cleanup;
}
sd_addr = &pSD;
if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
{
goto cleanup;
}
m_sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
m_sec_attr.lpSecurityDescriptor = pSD;
m_sec_attr.bInheritHandle = FALSE;
return TRUE;

cleanup:
if (pEveryoneSID)
FreeSid(pEveryoneSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
return FALSE;
}

void PipeIPC::Connect()
{
ConnectNamedPipe(m_hPipeHandle, nullptr);
}

void PipeIPC::DisConnect()
{
DisconnectNamedPipe(m_hPipeHandle);
}

//读取数据
bool PipeIPC::ReadData(__out std::string& datas, __out bool bIsPipeEnd)
{
if (INVALID_HANDLE_VALUE == m_hPipeHandle || nullptr == m_hPipeHandle)
{
InitPipeIPC();
}

DWORD cbRead = 0;//定义数据长度
DWORD cbData = 0;
if (ReadFile(m_hPipeHandle, &cbData, sizeof(cbData), &cbRead, nullptr) && sizeof(cbData) == cbRead)
{
DWORD error = GetLastError();
bIsPipeEnd = (error == ERROR_BROKEN_PIPE ? true : false);

datas.resize(cbData);

if (ReadFile(m_hPipeHandle, (LPVOID)datas.data(), cbData, &cbRead, nullptr) && cbData == cbRead)
{
return true;
}
}
else
{
DWORD dwError = GetLastError();
bIsPipeEnd = (dwError == ERROR_BROKEN_PIPE) ? true : false;
}

datas.resize(0);
return false;
}

//写入数据
bool PipeIPC::WriteData(__in const std::string& datas)
{
if (m_Role == USER_SERVER)
{
bool connect = ConnectNamedPipe(m_hPipeHandle, NULL);
if (!connect)
{
if (!InitPipeIPC())
{
DWORD error = GetLastError();
if (error != ERROR_PIPE_CONNECTED)
{
//cout << "客户端还没连接" << endl;
//连接失败
return false;
}
}
}
}

if (!IsInit())
{
if (!InitPipeIPC())
{
return false;
}
}

//连接成功!
DWORD wLen;
const DWORD cbData = datas.size() * sizeof(datas[0]);

if (!WriteFile(m_hPipeHandle, &cbData, sizeof(cbData), &wLen, NULL))
{
return false;
}
if (!WriteFile(m_hPipeHandle, datas.c_str(), datas.size() * sizeof(datas[0]), &wLen, NULL))
{
return false;
}

return true;
}

void PipeIPC::Release()
{
if (m_hPipeHandle)
{
DisconnectNamedPipe(m_hPipeHandle);
CloseHandle(m_hPipeHandle); // 关闭句柄
m_hPipeHandle = NULL;
}
}

定义与声明

1
2
__declspec(selectany) PipeIPC* pRead = new PipeIPC(USER_SERVER);
__declspec(selectany) PipeIPC* pWrite = new PipeIPC(USER_CLIENT);

使用

监听管道

随程序同时启动

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
   
BOOL StartPipeRead()
{
EventLog(LOG_ALL, "[IPC][THREAD] ,Create PipeReadThread Success, pipe = %p", pRead );
EventLog(LOG_ALL, "pipe = %p, pipe->IsInit()=%d", pRead, pRead->IsInit());

bool isPipeEnd = true;
while (true)
{
if (isPipeEnd)
{
pRead->Connect();
}

std::string datas;
if (!pRead->ReadData(datas, isPipeEnd))
{
if (isPipeEnd)
{
EventLog(LOG_ALL, "-----------[PIPE END]----------");
pRead->DisConnect();
}
}

datas = "Add";

// 数据处理
if (datas.find("start") != std::string::npos) // 启动成功
{
EventLog(LOG_ALL, " [PIPE] [REC] TrustAgentStart");
// 启动 管道客户端
if (!StartPipeWrite())
{
EventLog(LOG_ALL, " [PIPE] Failed to Create Client Pipe, GetLastError()=", GetLastError());
}
}
else if (!datas.empty())
{
EventLog(LOG_ALL, "[PIPE] [RECV] datas: %s", datas.c_str());
// 调用导出的接口
{
std::thread th(HandleFix, datas);
th.detach();

}
// NSPTRUST::SendRpcMsgToPlugin(POLICY_SENDTQA_USER, datas.c_str());
}
}
}

写管道

启动时机,同名管道的监听管道启动后再启动

1
2
3
4
5
6
7
BOOL StartPipeWrite()
{
if (pWrite->IsInit())
return true;
else
return pWrite->InitPipeIPC();
}

写数据

1
2
std::string datas = "Send data to PIPE Read";
pWrite->WriteData(datas);