Skip to content

Commit 8c126e9

Browse files
committed
ntl::device -> ntl::device<Extension>
ntl::except -> ntl::exception Add ntl::try_except function.
1 parent 3cef91a commit 8c126e9

File tree

14 files changed

+346
-226
lines changed

14 files changed

+346
-226
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,16 @@ Provides features to support a better development environment in the kernel.
143143
* ntl::driver
144144
* Class for DRIVER_OBJECT
145145
* Features
146-
* [x] DriverUnload [(tested)](./test/driver/src/main.cpp#L30)
147-
* [x] Create device [(tested)](./test/driver/src/main.cpp#L39)
146+
* [x] DriverUnload [(tested)](./test/driver/src/main.cpp#L73)
147+
* [x] Create device [(tested)](./test/driver/src/main.cpp#L44)
148148
* ntl::device
149149
* Class for DEVICE_OBJECT
150150
* Features
151151
* [x] Device Extension [(tested)](./test/driver/src/main.cpp#L39)
152152
* [ ] IRP_MJ_CREATE
153153
* [ ] IRP_MJ_CLOSE
154-
* [x] IRP_MJ_DEVICE_CONTROL [(tested)](./test/app/src/main.cpp#L77) [(tested)](./test/driver/src/main.cpp#L47)
155-
* ntl::driver_main [(tested)](./test/driver/src/main.cpp#L22)
154+
* [x] IRP_MJ_DEVICE_CONTROL [(tested)](./test/app/src/main.cpp#L77) [(tested)](./test/driver/src/main.cpp#L55)
155+
* ntl::driver_main [(tested)](./test/driver/src/main.cpp#L25)
156156
* Driver entry point for C++.
157157
* Called by expanding the stack to its maximum size with the ntl::expand_stack function.
158158
* ntl::rpc
@@ -281,7 +281,7 @@ If the SDK and WDK versions are different, builds are more likely to fail. **If
281281
include(cmake/CPM.cmake)
282282
283283
set(CRTSYS_NTL_MAIN ON) # use ntl::main
284-
CPMAddPackage("gh:ntoskrnl7/[email protected].7")
284+
CPMAddPackage("gh:ntoskrnl7/[email protected].8")
285285
include(${crtsys_SOURCE_DIR}/cmake/CrtSys.cmake)
286286
287287
# add driver

docs/ko-kr.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,16 @@ crtsys의 장점은 아래와 같습니다.
143143
* ntl::driver
144144
* DRIVER_OBJECT에 대한 클래스
145145
* 기능
146-
* [x] DriverUnload [(tested)](../test/driver/src/main.cpp#L30)
147-
* [x] Create device [(tested)](../test/driver/src/main.cpp#L39)
146+
* [x] DriverUnload [(tested)](../test/driver/src/main.cpp#L73)
147+
* [x] Create device [(tested)](../test/driver/src/main.cpp#L44)
148148
* ntl::device
149149
* DEVICE_OBJECT에 대한 클래스
150150
* Features
151151
* [x] Device Extension [(tested)](../test/driver/src/main.cpp#L39)
152152
* [ ] IRP_MJ_CREATE
153153
* [ ] IRP_MJ_CLOSE
154-
* [x] IRP_MJ_DEVICE_CONTROL [(tested)](../test/app/src/main.cpp#L77) [(tested)](../test/driver/src/main.cpp#L47)
155-
* ntl::driver_main [(tested)](../test/driver/src/main.cpp#L22)
154+
* [x] IRP_MJ_DEVICE_CONTROL [(tested)](../test/app/src/main.cpp#L77) [(tested)](../test/driver/src/main.cpp#L55)
155+
* ntl::driver_main [(tested)](../test/driver/src/main.cpp#L25)
156156
* C++ 용 드라이버 진입점
157157
* ntl::expand_stack 함수로 스택을 최대 크기로 확장하여 호출됩니다.
158158
* ntl::rpc
@@ -281,7 +281,7 @@ SDK와 WDK의 버전이 다르면 빌드가 실패할 가능성이 높으므로
281281
include(cmake/CPM.cmake)
282282
283283
set(CRTSYS_NTL_MAIN ON) # use ntl::main
284-
CPMAddPackage("gh:ntoskrnl7/[email protected].7")
284+
CPMAddPackage("gh:ntoskrnl7/[email protected].8")
285285
include(${crtsys_SOURCE_DIR}/cmake/CrtSys.cmake)
286286
287287
# add driver

include/.internal/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ Environment:
2626

2727
#define CRTSYS_VERSION_MAJOR 0
2828
#define CRTSYS_VERSION_MINOR 1
29-
#define CRTSYS_VERSION_PATCH 7
29+
#define CRTSYS_VERSION_PATCH 8
3030

3131
#endif // _CRTSYS_VERSION_

include/ntl/device

Lines changed: 121 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,106 +18,166 @@
1818
#endif
1919

2020
namespace ntl {
21-
class device {
22-
friend class device_dispatch_invoker;
21+
namespace device_control {
22+
struct code {
23+
code(ULONG code) : value(code) {}
24+
25+
auto device_type() const { return DEVICE_TYPE_FROM_CTL_CODE(value); }
26+
auto method() const { return METHOD_FROM_CTL_CODE(value); }
27+
auto function() const { return IoGetFunctionCodeFromCtlCode(value); }
28+
bool operator==(const code &rhs) const { return value == rhs.value; }
29+
bool operator==(ULONG rhs) const { return value == rhs; }
30+
bool operator==(int rhs) const { return value == static_cast<ULONG>(rhs); }
31+
32+
ULONG value;
33+
};
34+
35+
struct in_buffer {
36+
in_buffer(const void *ptr, size_t size) : ptr(ptr), size(size) {}
37+
const void *ptr;
38+
size_t size;
39+
};
40+
41+
struct out_buffer {
42+
out_buffer(void *ptr, size_t size) : ptr(ptr), size(size) {}
43+
void *ptr;
44+
size_t size;
45+
};
46+
47+
using dispatch_fn = std::function<void(const device_control::code &,
48+
const device_control::in_buffer &,
49+
device_control::out_buffer &)>;
50+
} // namespace device_control
51+
} // namespace ntl
52+
53+
namespace ntl {
54+
55+
namespace detail {
56+
57+
struct device_dispatchers {
58+
device_control::dispatch_fn on_device_control;
59+
};
2360

61+
template <typename Extension> struct device_extension_data;
62+
63+
template <> struct device_extension_data<void> {
64+
device_dispatchers dispatchers;
65+
};
66+
67+
template <typename Extension> struct device_extension_data {
68+
device_dispatchers dispatchers;
69+
Extension data;
70+
};
71+
72+
template <typename T> class device_extension;
73+
74+
template <> class device_extension<void> {
2475
public:
25-
using on_device_control_fn = std::function<void(uint32_t, const uint8_t *,
26-
size_t, uint8_t *, size_t *)>;
76+
device_extension() : device_(nullptr) {}
77+
device_extension(PDEVICE_OBJECT device) : device_(device) {}
78+
79+
detail::device_extension_data<void> *get_context() {
80+
return reinterpret_cast<detail::device_extension_data<void> *>(
81+
device_->DeviceExtension);
82+
}
2783

2884
private:
29-
friend class driver;
85+
PDEVICE_OBJECT device_;
86+
};
87+
88+
template <typename Extension> class device_extension {
89+
public:
90+
device_extension() : device_(nullptr) {}
91+
device_extension(PDEVICE_OBJECT device) : device_(device) {}
3092

31-
struct context_base {
32-
context_base(const std::type_info &type) : type(type) {}
33-
const std::type_info &type;
34-
on_device_control_fn on_device_control;
35-
};
93+
detail::device_extension_data<Extension> *get_context() {
94+
return reinterpret_cast<detail::device_extension_data<Extension> *>(
95+
device_->DeviceExtension);
96+
}
97+
98+
Extension &extension() { return get_context()->data; }
3699

37-
template <typename T> class context;
100+
private:
101+
PDEVICE_OBJECT device_;
102+
};
103+
} // namespace detail
38104

39-
template <> struct context<void> : public context_base {
40-
context() : context_base(typeid(void)) {}
41-
};
105+
using device_type = DEVICE_TYPE;
42106

43-
template <typename T> struct context : public context_base {
44-
context() : context_base(typeid(T)) {}
45-
T data;
46-
};
107+
class device_options {
108+
friend class driver;
47109

48110
public:
49-
using type_t = DEVICE_TYPE;
111+
device_options() : type_(FILE_DEVICE_UNKNOWN), exclusive_(false) {}
50112

51-
class options {
52-
friend class driver;
53-
friend class device;
113+
device_options &name(const std::wstring &name) {
114+
name_ = name;
115+
return *this;
116+
}
117+
device_options &type(device_type type) {
118+
type_ = type;
119+
return *this;
120+
}
121+
device_options &exclusive(bool exclusive = true) {
122+
exclusive_ = exclusive;
123+
return *this;
124+
}
54125

55-
public:
56-
options() : type_(FILE_DEVICE_UNKNOWN), exclusive_(false) {}
126+
const std::wstring &name() const { return name_; }
127+
device_type type() const { return type_; }
128+
bool exclusive() const { return exclusive_; }
57129

58-
options &name(const std::wstring &name) {
59-
name_ = name;
60-
return *this;
61-
}
62-
options &type(type_t type) {
63-
type_ = type;
64-
return *this;
65-
}
66-
options &exclusive(bool exclusive = true) {
67-
exclusive_ = exclusive;
68-
return *this;
69-
}
130+
private:
131+
bool exclusive_;
132+
std::wstring name_;
133+
device_type type_;
134+
};
70135

71-
private:
72-
bool exclusive_;
73-
std::wstring name_;
74-
type_t type_;
75-
};
136+
template <typename Extension>
137+
class device : public detail::device_extension<Extension> {
138+
friend class device_dispatch_invoker;
139+
friend class driver;
76140

77141
protected:
78-
device(PDEVICE_OBJECT device, const options &opts,
79-
std::function<void()> finalizer)
80-
: object_(device), name_(opts.name_), finalizer_(finalizer) {}
142+
device(PDEVICE_OBJECT device, const device_options &opts)
143+
: detail::device_extension<Extension>(device), object_(device),
144+
name_(opts.name()) {}
81145

82146
private:
83147
device(const device &) = delete;
84148

85149
public:
86150
device() : object_(nullptr) {}
87151

88-
device(device &&other) { *this = std::move(other); }
152+
device(device &&other) : detail::device_extension<Extension>(other.object_) {
153+
*this = std::move(other);
154+
}
89155

90156
device &operator=(device &&rhs) {
91157
object_ = rhs.detach();
92158
name_.swap(rhs.name_);
93-
finalizer_ = std::move(rhs.finalizer_);
94159
return *this;
95160
}
96161

97162
~device() {
98163
auto obj = detach();
99164
if (obj) {
100-
if (finalizer_)
101-
finalizer_();
165+
if (obj->DeviceExtension)
166+
reinterpret_cast<detail::device_extension_data<Extension> *>(
167+
obj->DeviceExtension)
168+
->~device_extension_data();
102169
IoDeleteDevice(obj);
103170
}
104171
}
105172

106-
private:
107-
template <typename Extension> context<Extension> *get_context() {
108-
return reinterpret_cast<context<Extension> *>(object_->DeviceExtension);
173+
protected:
174+
detail::device_dispatchers &dispatchers() {
175+
return detail::device_extension<Extension>::get_context()->dispatchers;
109176
}
110177

111178
public:
112-
template <typename Extension> Extension &extension() {
113-
auto ext = get_context<Extension>();
114-
if (ext->type != typeid(Extension))
115-
throw std::runtime_error("bad type");
116-
return ext->data;
117-
}
118-
119-
device &on_device_control(on_device_control_fn &&f) {
120-
get_context<void>()->on_device_control = f;
179+
device &on_device_control(device_control::dispatch_fn &&f) {
180+
dispatchers().on_device_control = f;
121181
return *this;
122182
}
123183

@@ -127,7 +187,7 @@ public:
127187
return name_;
128188
}
129189

130-
type_t type() const {
190+
device_type type() const {
131191
if (!object_)
132192
throw std::runtime_error("invalid device object.");
133193
return object_->DeviceType;
@@ -141,6 +201,5 @@ public:
141201
private:
142202
PDEVICE_OBJECT object_;
143203
std::wstring name_;
144-
std::function<void()> finalizer_;
145204
};
146205
} // namespace ntl

0 commit comments

Comments
 (0)