Skip to content

Commit b345fc3

Browse files
authored
Merge pull request #21 from ntoskrnl7/features/ntl
Features/ntl
2 parents 3cef91a + 0efe0af commit b345fc3

File tree

14 files changed

+344
-228
lines changed

14 files changed

+344
-228
lines changed

README.md

Lines changed: 6 additions & 6 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
151-
* [x] Device Extension [(tested)](./test/driver/src/main.cpp#L39)
151+
* [x] Device Extension [(tested)](./test/driver/src/main.cpp#L33)
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: 6 additions & 6 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
151-
* [x] Device Extension [(tested)](../test/driver/src/main.cpp#L39)
151+
* [x] Device Extension [(tested)](../test/driver/src/main.cpp#L33)
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: 118 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,106 +18,163 @@
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+
namespace detail {
55+
namespace device {
56+
struct dispatchers_t {
57+
device_control::dispatch_fn on_device_control;
58+
};
59+
60+
template <typename Extension> struct extension_data_t;
61+
62+
template <> struct extension_data_t<void> { dispatchers_t dispatchers; };
2363

64+
template <typename Extension> struct extension_data_t {
65+
dispatchers_t dispatchers;
66+
Extension data;
67+
};
68+
69+
template <typename T> class extension_t;
70+
71+
template <> class extension_t<void> {
2472
public:
25-
using on_device_control_fn = std::function<void(uint32_t, const uint8_t *,
26-
size_t, uint8_t *, size_t *)>;
73+
extension_t() : device_(nullptr) {}
74+
extension_t(PDEVICE_OBJECT device) : device_(device) {}
75+
76+
extension_data_t<void> *get_context() {
77+
return reinterpret_cast<extension_data_t<void> *>(device_->DeviceExtension);
78+
}
2779

2880
private:
29-
friend class driver;
81+
PDEVICE_OBJECT device_;
82+
};
3083

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-
};
84+
template <typename Extension> class extension_t {
85+
public:
86+
extension_t() : device_(nullptr) {}
87+
extension_t(PDEVICE_OBJECT device) : device_(device) {}
3688

37-
template <typename T> class context;
89+
extension_data_t<Extension> *get_context() {
90+
return reinterpret_cast<extension_data_t<Extension> *>(
91+
device_->DeviceExtension);
92+
}
3893

39-
template <> struct context<void> : public context_base {
40-
context() : context_base(typeid(void)) {}
41-
};
94+
Extension &extension() { return get_context()->data; }
4295

43-
template <typename T> struct context : public context_base {
44-
context() : context_base(typeid(T)) {}
45-
T data;
46-
};
96+
private:
97+
PDEVICE_OBJECT device_;
98+
};
99+
} // namespace device
100+
} // namespace detail
101+
102+
using device_type = DEVICE_TYPE;
103+
104+
class device_options {
105+
friend class driver;
47106

48107
public:
49-
using type_t = DEVICE_TYPE;
108+
device_options() : type_(FILE_DEVICE_UNKNOWN), exclusive_(false) {}
50109

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

55-
public:
56-
options() : type_(FILE_DEVICE_UNKNOWN), exclusive_(false) {}
123+
const std::wstring &name() const { return name_; }
124+
device_type type() const { return type_; }
125+
bool is_exclusive() const { return exclusive_; }
57126

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-
}
127+
private:
128+
std::wstring name_;
129+
device_type type_;
130+
bool exclusive_;
131+
};
70132

71-
private:
72-
bool exclusive_;
73-
std::wstring name_;
74-
type_t type_;
75-
};
133+
template <typename Extension>
134+
class device : public detail::device::extension_t<Extension> {
135+
friend class device_dispatch_invoker;
136+
friend class driver;
76137

77138
protected:
78-
device(PDEVICE_OBJECT device, const options &opts,
79-
std::function<void()> finalizer)
80-
: object_(device), name_(opts.name_), finalizer_(finalizer) {}
139+
device(PDEVICE_OBJECT device, const device_options &opts)
140+
: detail::device::extension_t<Extension>(device), object_(device),
141+
name_(opts.name()) {}
81142

82143
private:
83144
device(const device &) = delete;
84145

85146
public:
86147
device() : object_(nullptr) {}
87148

88-
device(device &&other) { *this = std::move(other); }
149+
device(device &&other)
150+
: detail::device::extension_t<Extension>(other.object_) {
151+
*this = std::move(other);
152+
}
89153

90154
device &operator=(device &&rhs) {
91155
object_ = rhs.detach();
92156
name_.swap(rhs.name_);
93-
finalizer_ = std::move(rhs.finalizer_);
94157
return *this;
95158
}
96159

97160
~device() {
98161
auto obj = detach();
99162
if (obj) {
100-
if (finalizer_)
101-
finalizer_();
163+
if (obj->DeviceExtension)
164+
detail::device::extension_t<Extension>::get_context()
165+
->~extension_data_t();
102166
IoDeleteDevice(obj);
103167
}
104168
}
105169

106-
private:
107-
template <typename Extension> context<Extension> *get_context() {
108-
return reinterpret_cast<context<Extension> *>(object_->DeviceExtension);
170+
protected:
171+
detail::device::dispatchers_t &dispatchers() {
172+
return detail::device::extension_t<Extension>::get_context()->dispatchers;
109173
}
110174

111175
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;
176+
device &on_device_control(device_control::dispatch_fn &&f) {
177+
dispatchers().on_device_control = f;
121178
return *this;
122179
}
123180

@@ -127,7 +184,7 @@ public:
127184
return name_;
128185
}
129186

130-
type_t type() const {
187+
device_type type() const {
131188
if (!object_)
132189
throw std::runtime_error("invalid device object.");
133190
return object_->DeviceType;
@@ -141,6 +198,5 @@ public:
141198
private:
142199
PDEVICE_OBJECT object_;
143200
std::wstring name_;
144-
std::function<void()> finalizer_;
145201
};
146202
} // namespace ntl

0 commit comments

Comments
 (0)