Chương 1 Tổng quan
1.1 Chương trình quản lý phòng máy bao gồm những gì?
Trong quá trình khảo sát các chương trình quản lý phòng máy đang sử dụng
tại Việt Nam, chúng em tạm phân loại các yêu cầu đề ra là : các yêu cầu cần, các
yêu cầu đủ, và các yêu cầu mở rộng.
1.1.1 Các yêu cầu cần:
Bản thân chương trình quản lý máy thuê Internet phải có khả năng tính tiền
cước hợp lý cho người sử dụng. Người thuê máy cần cảm thấy việc tính cước đúng
và làm họ hài lòng. Ngoài ra, nếu phòng máy còn có phục vụ món ăn, dịch vụ như:
tạp chí, sách báo… thì một yêu cầu cần khác là cần tính phí phục vụ cho người
dùng. Đối với người dùng, họ cảm thấy hài lòng khi việc phục vụ được nhanh
chóng và chu đáo.
1.1.2 Các yêu cầu đủ:
Ngoài hai yêu cầu trên, việc bảo mật bảo mật và kiểm duyệt nội dung web
cũng rất quan trọng do nó cũng ảnh hưởng một phần đến việc kinh doanh (chẳng
hạn, thể gây ảnh hưởng uy tín phòng máy khi lướt web đen…). Vì vậy, các yêu cầu
kiểm soát hệ thống máy khách được đặt ra như quan sát màn hình máy khách, đọc
nội dung người dùng gõ…
1.1.3 Các yêu cầu mở rộng:
Ngoài các dạng yêu cầu trên, các yêu cầu còn lại là các yêu cầu mở rộng.
Thật ra, các yêu cầu mở rộng chỉ có tính tương đối. Tùy thuộc yêu cầu đặt ra cho
phần mềm mà ta có thể xem xét thêm các yêu cầu mở rộng như là yêu cầu đủ. Các
yêu cầu mở rộng thường thấy là : lọc liên kết web, nội dung web, nhắn tin di động,
chat nội bộ giữa các máy khách với nhau, đa ngôn ngữ…
1
1.2 Các chương trình quản lý phòng máy hiện nay ở Việt
Nam.
1.2.1 Cyber Station Manager
Cyber Station Manager là phần mềm quản lý khách hàng, thời gian sử
dụng máy trạm, điều khiển máy trạm do công ty trách nhiệm hữu hạn Đan Thanh
viết. Chương trình có các chức năng chính:
o Quản lý thông tin các máy trạm
o Quản lý thông tin các hội viên
o Quản lý hóa đơn
1.2.2 Internet Café Software:
Do công ty PA Việt Nam 65 đường Sư Vạn Hạnh nối dài Q.10 Tp. Hồ
Chí Minh viết. Các tính năng chính:
o Quản lý thông tin các máy trạm
1.2.3 iSystem 3.0 :
Hệ phần mềm chuyên nghiệp cho máy dịch vụ game – Internet, gồm
hai phần :
o iSystem hỗ trợ quản trị mạng từ bất cứ máy nào trong mạng nội bộ, hỗ trợ lọc
web đen, biên tập danh bạ web, phân vùng khởi động, hỗ trợ kết nối Internet
và ADSL.
o iNetman hỗ trợ quản lý đồng thời nhiều loại dịch vụ (game, Internet…) và
quản lý bán hàng.
Do công ty TBNet 111 Lý Thường Kiệt Tp Thái Bình – tỉnh Thái Bình.
1.2.4 EasyCafe :
Do công ty Tinasoft tại Thổ Nhĩ Kỳ viết.
Các chức năng:
o Quản lý thông tin các máy trạm.
2
o Quản lý thông tin các hội viên.
o Quản lý hóa đơn.
o Lọc thông tin.
o Nhắn tin di dộng.
o Điều khiển từ xa các máy trạm.
1.3 Các ưu khuyết điểm của các chương trình trên.
1.3.1 Cyber Station Manager
Ưu điểm :
Phần mềm quản lý chi tiết việc phân loại khách hàng gồm : hội viên, khách
vãng lai và người quản trị cả Server và Client.
Các cách tính cước cho người dùng phong phú: trả tiền trước, trả tiền sau,
cộng dồn tiền cước các máy(cho phép đổi máy sử dụng khi đang sử dụng máy nào
đó). Cộng thêm thời gian sử dụng miễn phí cho khách. Thêm phí tự động cho khách
khi khách có yêu cầu.
Khuyết điểm:
Cài đặt phức tạp( do dùng MySQL).
Sử dụng Tiếng Việt không dấu.
Các chức năng quản lý máy trạm đơn giản.
Các chức năng điều khiển từ xa còn ít.
1.3.2 Internet Café Software
Ưu điểm :
- Giao diện đơn giản, dễ dùng. Có thể chuyển đổi máy cho khách
hàng.
- Màn hình screen che khá hiệu quả .
Khuyết điểm:
- Các chức năng không đầy đủ( Chương trình chỉ có phần tính cước,
in báo biểu).
3
- Phải đổi tên máy ngay khi bắt đầu sử dụng bên phía Server. Máy
phải khởi động lại.
1.3.3 iSystem 3.0
Ưu điểm :
- Giao diện đơn giản, dễ dùng. Có thể chuyển đổi máy cho khách
hàng.
Khuyết điểm:
- Mặc dù có một số chức năng quản trị máy từ xa, nhưng vẫn còn rất ít
(chỉ có tắt máy, nhắn tin từ máy chủ).
- Phải đổi tên máy ngay khi bắt đầu sử dụng bên phía Server. Máy
phải khởi động lại.
1.3.4 Easy Café:
Ưu điểm :
- Có gần như đầy đủ tất cả các chức năng quản lý cần thiết và mở
rộng.
- Hỗ trợ đa ngôn ngữ.
- Có thể xem đây phần mềm điển hình về việc quản lý các máy trạm ở
phòng cho thuê dịch vụ Internet.
Khuyết điểm:
- Vì phải quản lý chi tiết mọi thứ nên giao diện phức tạp, khó dùng.
- Không hỗ trợ tiếng Việt mặc dù là phần mềm đa ngôn ngữ.
4
Chương 2 Xây dựng chương trình quản lý phòng máy
2.1 Xác định yêu cầu:
2.1.1 Các yêu cầu chức năng:
Xây dựng phần mềm quản lý phòng thuê Internet, chương trình có
yêu cầu quản lý những tính năng cần là:
Các tính năng cần là:
Tính cước sử dụng máy
Tính cước phục vụ món
Quản lý báo cáo
Các tính năng đủ là:
Kiểm soát các họat động máy khách và nội dung sử dụng của người
dùng
2.1.2 Các yêu cầu phi chức năng:
2.2 Phân tích thiết kế hệ thống:
2.2.1 Xây dựng Use Case:
2.2.1.1
Xác định Actor và Use Case phía Server:
Actor: Người sử dụng chương trình Server ở máy chủ - Người quản
lý.
Use Case:
Start Server: Chạy chương trình Server.
Login: Cho phép Client sử dụng máy tính với trạng thái
username=”anonymous” , password=””.
Logout: Không cho phép Client sử dụng máy tính.
Paid: Tính tiền người dùng.
5
Banner: Thông tin (các nội quy của phòng máy ) người quản
lý muốn cho khách hàng biết.
Report :
Report Debit: Thống kê các khách hàng nợ.
Report Daily: Thống kê các thông tin kết nối của các
máy khách hằng ngày.
Report Month: Thống kê tình trạng sử dụng các máy
theo tháng.
Option :
Manage Cafeteria: Người quản lý có thể xem, sửa hay
bổ sung các loại món ăn, thức uống.
Manage Kind of Food: Người quản lý có thể xem, sửa
hay bổ sung các món ăn, thức uống.
Manage Price Day: Người quản lý có thể xem, sửa hay
bổ sung giá truy cập internet theo ngày cụ thể.
Manage Debit: Người quản lý thêm vào cơ sở dữ liệu
khách hàng còn nợ.
Manage Member: Người quản lý có thể xem, sửa hay bổ
sung thành viên.
Administration:
Lock Key: Cho phép người quản lý có thể khóa tất cả
các phím hay một số phím trên một máy khách đang sử dụng.
Log Key: Cho phép người quản lý có thể ghi nhận lại
các phím khách hàng sử dụng trên một máy khách đang sử dụng.
Manage Application: Cho phép người quản lý có thể
biết được các ứng dụng chạy trên máy khách, và người quản lý cũng có thể bật hay
tắt một ứng dụng nào đó.
Manage Service: Cho phép người quản lý có thể biết
được các service chạy trên máy khách, và người quản lý cũng có thể thay đổi loại
6
khởi động (Automatic, Manual hay Disable) hay cũng có thể trạng thái service(Start
hay Stop).
Manage Remote Computer: Cho phép người quản lý có
thể Logout, Restart hay Shutdown một máy khách bất kỳ hay cho tất cả các máy
theo các tinh chỉnh về thời gian thực hiện.
Send Message: Cho phép người quản lý có thể gởi tin
nhắn đến một máy khách bất kỳ hay cho tất cả các máy.
Snapshot: Cho phép người quản lý có thể chụp hình tĩnh
hay hình động máy khách. Khi chụp tĩnh, tối đa chụp được 4 máy khách. Khi chụp
động thì chụp được 1 máy khách.
2.2.1.2
Xác định các Actor và Use Case phía Client:
Actor: Người sử dụng chương trình Screen.
Use Case:
Connect: thực hiện kết nối với Server để vào trạng thái chờ.
Login Member: thực hiện login vào Server dưới hình thức
Member.
Actor: Người sử dụng chương trình Client.
Use Case:
Connect: thực hiện kết nối với Server để vào trạng thái sử
dụng.
Order: thực hiện đặt món ăn từ danh sách với Server.
2.2.1.3 Mô hình Use Case:
2.2.1.3.1 Phía Server
7
Start Server (from Use Case)
Login (from Use Case)
Logout (from Use Case)
Paid (from User Case)
Administration (from User)
User
Set Banner (from Use Case)
Change Option (from User)
Report (from Use Case)
Service order (from User)
Month Report (from User)
Daily Report (from User)
Debit Report (from User)
User
Hình 2-1 Mô hình Use Case tổng quát
Hình 2-2 Mô hình Use Case Report
8
Manage Price Day (from User)
Manage Debit (from User)
Manage Kind of Food (from User)
User
Manage Cafeteria (from User)
Manage Member (from User)
Log Key (from User)
Lock Key (from User)
Manage Application (from User)
User
Snap Shot (from User)
Manage Service (from User)
Send Message (from User)
Manage Remote Computer (from User)
Apply Policy (from User)
Hình 2-3 Mô hình Use Case Manage
Hình 2-4 Mô hình Use Case Administrator
9
2.2.1.3.2 Phía Client:
2.2.1.3.2.1 Screen:
Connect (from User)
Login Member (from User)
User
Hình 2-5 Mô hình Use case Screen
2.2.1.3.2.2 Client:
Connect
Order (from User)
User
Hình 2-6 Mô hình Use case Client
10
2.2.2 Đặt tả Use Case:
2.2.2.1
Phía Server:
2.2.2.1.1 Start Server Use Case:
Tên Use Case: Start Server.
Mô tả : Server khởi động và lắng nghe kết nối.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Người dùng khởi động chương trình.
+ Chương trình sẽ thực hiện việc mở cơ sở dữ liệu.
+ Kiểm tra thông tin kết nối .
+ Thực hiện việc lắng nghe các kết nối từ máy khách.
- Dòng sự kiện khác:
+ Nếu có lỗi về việc mở cơ sở dữ liệu thì chương trình sẽ báo
lỗi và thoát ra khỏi chương trình.
+ Nếu không có thông tin về số lượng máy có thể kết nối thì sẽ
xuất thông báo yêu cầu nhập thông tin.
+ Nếu lần trước Server bị “chết”, thì bây giờ Server sẽ kiểm tra
lại kết nối từ các máy khách.
- Điều kiện tiên quyết:
+ Phải có cơ sở dữ liệu.
- Điều kiện bổ sung :
+ Chương trình phải đăng ký các Active X về List View.
- Điểm mở rộng:
+ Không có.
2.2.2.1.2 Login Use Case :
Tên Use Case : Login.
Mô tả :
11
Người quản lý có thể cho máy khách login với tư cách là anonymous.
Dòng sự kiện :
-Dòng sự kiện chính :
+ Use case này bắt đầu khi người quản lý chọn Login.
+ Server kiểm tra xem máy khách có đang ở trạng thái chờ ?
+ Nếu hợp lệ Server gởi thông điệp đến máy khách.
+ Client nhận thông điệp sẽ tắt màn hình Screen và gởi thông
điệp chấp nhận về Server.
+ Server nhận thông điệp sẽ cho phép khách hàng ở máy khách
có thể sử dụng với tư cách anonymous. Chương trình bắt đầu
tính tiền cho khách hàng từ lúc này cho đến lúc khách hàng kết
thúc sử dụng
- Dòng sự kiện khác :
+ Nếu Server kiểm tra máy khách không phải ở trạng thái chờ
thì không cho Login.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Máy chuyển từ trạng thái chờ sang trạng thái sử dụng.
- Điểm mở rộng:
+ Không có.
2.2.2.1.3 Logout Use Case:
Tên Use Case : Logout.
Mô tả : Kết thúc việc khách hàng sử dụng máy khách.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi khách hàng chọn Logout.
+ Server gởi thông điệp cho Client, cập nhật lại database.
12
+ Client nhận thông điệp và tắt hết các chương trình đang sử dụng.
+ Client bật màn hình che( màn hình Screen).
+ Màn hình che connect lại với Server.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Client phải Login vào Server trước.
- Hậu điều kiện:
+ Máy chuyển từ trạng thái sử dụng sang trạng thái chờ.
- Điểm mở rộng:
+ Không có .
2.2.2.1.4 Paid Use Case:
Tên Use Case : Paid.
Mô tả : Kết thúc việc khách hàng sử dụng máy khách và tính tiền.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý chọn Paid.
+ Server gởi thông điệp cho Client.
+ Client nhận thông điệp và tắt hết các chương trình đang sử dụng.
+ Client bật màn hình che( màn hình Screen).
+ Server tính tiền sử dụng và tiền các dịch vụ liên quan và xuất ra
màn hình.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Client phải Login vào Server trước.
- Hậu điều kiện:
+ Máy chuyển từ trạng thái sử dụng sang trạng thái chờ.
13
- Điểm mở rộng:
+ Không có.
2.2.2.1.5 Service Order Use Case:
Tên Use Case : Service Order.
Mô tả : Phục vụ món ăn cho khách hàng.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi khách hàng yêu cầu phục vụ món ăn thức
uống.
+ Người quản lý chọn máy khách mà khách hàng yêu cầu phục vụ.
Khi đó danh sách các món ăn, thức uống mà khách hàng yêu cầu hiện ra.
+ Người quản lý phục vụ lần lượt các món ăn. Lúc đó, tiền dịch vụ
được cập nhật vào trong tiền sử dụng máy.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Máy khách đang ở trạng thái sử dụng.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.6 Set Banner Use Case:
Tên Use Case: Banner.
Mô tả : Thông báo các quy định về sử dụng phòng máy cho khách hàng.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý chọn Set Banner.
+ Nhập các quy định mà người quản lý muốn khách hàng cần biết.
14
+ Server gởi thông điệp đến tất cả các máy khách có kết nối với
Server.
+ Client nhận thông điệp sẽ cập nhật thông báo.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Máy khách đang ở trạng thái sử dụng.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.7 Daily Report Use Case:
Tên Use Case: Daily Report.
Mô tả: Hiển thị thông tin kết nối của các máy khách hằng ngày.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý chọn thống kê hàng ngày.
+ Chương trình đọc cơ sở dữ liệu từ bảng Daily Report và xuất ra
màn hình.
- Dòng sự kiện khác:
+ Nếu có lỗi cơ sở dữ liệu thì chương trình sẽ hiển thị thông báo.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.8 Month Report Use Case:
15
Tên Use Case: Daily Report
Mô tả: Hiển thị thông tin tiền của máy khách kiếm được trong cả tháng
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý chọn Month Report.
+ Chương trình đọc cơ sở dữ liệu từ bảng Month Report và xuất ra
màn hình.
- Dòng sự kiện khác:
+ Nếu có lỗi cơ sở dữ liệu thì chương trình sẽ hiển thị thông báo.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.9 Debit Report Use Case:
Tên Use Case: Debit Report.
Mô tả: Hiển thị danh sách các khách hàng còn nợ.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý chọn biểu tượng Debit
Report.
+ Chương trình đọc cơ sở dữ liệu từ bảng Debit Report và xuất ra
màn hình.
+ Khi người dùng chọn một khách hàng nợ thì thông tin chi tiết về
người khách nợ đó sẽ xuất ra màn hình.
- Dòng sự kiện khác:
+ Nếu có lỗi cơ sở dữ liệu thì chương trình sẽ hiển thị thông báo.
16
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.10 Manage Kind of Food Use Case:
Tên Use Case: Kind of Food.
Mô tả : Người quản lý có thể xem, sửa hay bổ sung các loại món ăn, thức
uống.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case này bắt đầu khi người quản lý chọn chức năng
quản lý loại món ăn, thức uống.
+ Màn hình xuất danh sách các loại món ăn, thức uống.
+ Người quản lý có thể chọn chức năng edit để sửa đổi
thông tin: luồng sự kiện phụ là sửa đổi một loại thức ăn
được kích hoạt.
+ Người quản lý có thể chọn chức năng Add new để thêm
thông tin luồng sự kiện phụ là thêm một loại thức ăn được
kích hoạt.
+ Người quản lý có thể chọn chức năng Delete để xóa
thông tin: luồng sự kiện phụ là xóa một loại thức ăn được
kích hoạt.
Sửa đổi một loại thức ăn:
+ Chọn loại thức ăn.
+ Nhập mới tên loại thức ăn.
+ Chọn chức năng Edit.
17
+ Chương trình sẽ cập nhật lại cơ sở dữ liệu.
Thêm một loại thức ăn:
+ Nhập tên loại thức ăn.
+ Chọn chức năng Add.
+ Chương trình sẽ cập nhật lại cơ sở dữ liệu.
Xóa một lọai thức ăn:
+ Chọn loại thức ăn.
+ Chọn chức năng Delete.
+ Chương trình sẽ cập nhật lại cơ sở dữ liệu.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.11 Manage Cafeteria Use Case:
Tên Use Case: Manage Cafeteria.
Mô tả: Người quản lý có thể xem, sửa hay bổ sung các món ăn.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case này bắt đầu khi người quản lý chọn chức năng
quản lý thức ăn, thức uống.
+ Màn hình xuất danh sách các món ăn, thức uống.
+ Người quản lý có thể chọn chức năng edit để sửa đổi
thông tin: luồng sự kiện phụ là sửa đổi thức ăn, thức uống
được kích hoạt.
18
+ Người quản lý có thể chọn chức năng Add new để thêm
thông tin luồng sự kiện phụ là thêm thức ăn, thức uống
được kích hoạt.
+ Người quản lý có thể chọn chức năng Delete để xóa
thông tin:luồng sự kiện phụ là xóa thức ăn, thức uống được
kích hoạt.
Sửa đổi thức ăn, thức uống:
+ Chọn thức ăn, thức uống.
+ Nhập mới các thông tin cần thiết như tên , giá
cả…
+ Chọn chức năng Edit.
+ Chương trình sẽ cập nhật lại cơ sở dữ liệu.
Thêm thức ăn, thức uống:
+ Nhập mới các thông tin cần thiết như tên , giá
cả… của thức ăn, thức uống.
+ Chọn chức năng Add.
+ Chương trình sẽ cập nhật lại cơ sở dữ liệu.
Xóa thức ăn, thức uống:
+ Chọn thức ăn, thức uống.
+ Chọn chức năng Delete.
+ Chương trình sẽ cập nhật lại cơ sở dữ liệu.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
19
2.2.2.1.12 Manage Price Day Use Case:
Tên Use Case: Manage Price Day.
Mô tả: Người quản lý có thể xem, sửa hay bổ sung giá truy cập internet theo
ngày cụ thể.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case này bắt đầu khi người quản lý chọn chức năng
quản lý giá dịch vụ.
+ Người quản lý chọn ngày cần quản lý.
+ Màn hình xuất giá truy cập 7 ngày trong tuần mà ngày đã
chọn thuộc vào.
+ Người quản lý chọn các giờ rồi chọn chức năng edit để
sửa đổi giá cả.
- Dòng sự kiện khác:
+ Nếu không chọn thì giá cả là mặc định.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.13 Manage Debit Use Case:
Tên Use Case: Manage Debit
Mô tả : Người quản lý thêm vào cơ sở dữ liệu khách hàng còn nợ
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case này bắt đầu khi người quản lý chọn chức năng
quản lý khách hàng nợ.
20
+ Màn hình sẽ hiển thị các thông tin cho người quản lý
nhập mới.
+ Người quản lý chọn máy mà khách hàng đã sử dụng, khi
đó danh sách các giờ Login vào máy đó sẽ xuất hiện. Người
quản lý chọn một trong số các giờ bắt đầu đó.
+ Sau đó nhập vào một số thông tin (bao gồm Tên, Địa chỉ,
Số điện thoại, tiền trả trước ….).
+ Sau khi nhập xong, chương trình sẽ lưu xuống cơ sở dữ
liệu
- Dòng sự kiện khác:
+ Không có
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.14 Manage Member Use Case:
Tên Use Case :Manage Member.
Mô tả : Người quản lý
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case này bắt đầu khi người quản lý chọn chức năng
quản lý thành viên của phòng máy.
+ Chương trình xuất hiện cửa sổ mới có danh sách các
thành viên.
21
+ Người quản lý có thể chọn chức năng edit để sửa đổi
thông tin: luồng sự kiện phụ là sửa đổi thành viên được
kích hoạt.
+ Người quản lý có thể chọn chức năng Add new để thêm
thông tin luồng sự kiện phụ là thêm thành viên được kích
hoạt.
+ Người quản lý có thể chọn chức năng Delete để xóa 1
record luồng sự kiện phụ là xóa thành viên được kích hoạt.
Sửa đổi thành viên:
+ Chọn thành viên.
+ Nhập mới các thông tin cần thiết như tên , địa
chỉ, số điện thoại…
+ Chọn chức năng Edit.
+ Chương trình cập nhật các thông tin thay đổi
vào cơ sở dữ liệu.
Thêm thức ăn, thức uống:
+ Nhập mới các thông tin cần thiết như tên , địa
chỉ, số điện thoại…của thành viên.
+ Chọn chức năng Add.
+ Chương trình lưu thông tin vào cơ sở dữ liệu.
Xóa thức ăn, thức uống:
+ Chọn thành viên.
+ Chọn chức năng Delete.
+ Chương trình xóa thông tin trong cơ sở dữ liệu.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
22
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.15 Lock Keys Use Case :
Tên Use Case: Lock Keys.
Mô tả : Cho phép người quản lý khóa các phím của máy khách.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý yêu cầu khóa phím.
+ Người quản lý chọn máy khách mà người quản lý muốn
khóa.
+ Chọn chế độ khóa là khóa tất cả phím, khóa phím F1-
>F2, khóa phím A->Z, khóa phím số , khóa phím dấu, khóa
phím hỗ trợ, khóa phím bất kỳ.
+ Khi đó Server sẽ gởi thông điệp đến máy khách, máy
khách nhận thông điệp sẽ thực hiện khóa phím tương ứng
với chế độ khóa.
+ Nếu thực hiện thành công thì máy khách sẽ gởi thông
điệp báo cho Server là khóa thành công.
+ Để kết thúc việc khóa, người quản lý chọn Mở khóa tất cả
+ Khi đó Server sẽ gởi thông điệp đến máy khách, máy
khách nhận thông điệp sẽ thực hiện mở khóa tất cả các
phím.
+ Nếu thực hiện thành công thì máy khách sẽ gởi thông
điệp báo cho Server là mở khóa thành công.
- Dòng sự kiện khác:
+ Nếu không thành công thì máy khách gởi thông điệp
cho Server báo là không thành công.
23
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.16 Log Keys Use Case :
Tên Use Case: Log Keys.
Mô tả : Cho phép người quản lý có thể ghi nhận lại các phím khách hàng sử
dụng trên máy khách.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý yêu cầu ghi nhận
phím.
+ Người quản lý chọn máy khách mà người quản lý muốn
ghi nhận phím.
+ Chọn bắt đầu ghi nhận.
+ Khi đó Server sẽ gởi thông điệp đến máy khách, máy
khách nhận thông điệp sẽ ghi nhận các phím người dùng đã
nhấn.
+ Người quản lý muốn xem những thông tin đã ghi nhận, sẽ
dừng tiến trình ghi nhận thông tin. Khi đó Server sẽ gởi
thông điệp đến máy khách, máy khách nhận thông điệp sẽ
thực hiện gởi thông tin ghi nhận cho Server
+ Nếu nhận thông tin thành công Server sẽ thông báo thành
công.
+ Người quản lý có thể xem thông tin ghi nhận.
- Dòng sự kiện khác:
24
+ Không có.
- Điều kiện tiên quyết:
+ Máy khách phải đang ở trạng thái sử dụng.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.17 Manage Application Use Case:
Tên Use Case: Manage Application.
Mô tả : Cho phép người quản lý có thể biết được các ứng dụng chạy trên
máy khách, và người quản lý cũng có thể bật hay tắt một ứng dụng nào đó.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý yêu cầu quản lý ứng
dụng trên máy khách.
+ Người quản lý chọn máy khách mà người quản lý muốn
xem danh sách các ứng dụng.
+ Nếu người quản lý chọn xem danh sách các ứng dụng:
Server gởi thông điệp yêu cẩu danh sách đến máy khách,
máy khách thực hiện việc ghi lại danh sách các ứng dụng
đang chạy ở máy khách và gởi về Server.
+ Nếu người quản lý chọn bật một ứng dụng: màn hình yêu
cầu nhập các thông tin cần thiết (như tên ứng dụng, đường
dẫn…) để bật ứng dụng, và Server gởi yêu cầu đến máy
khách. Máy khách nhận thông điệp sẽ bật ứng dụng tương
ứng.
25
+ Nếu người quản lý chọn tắt một ứng dụng: người quản lý
chọn một ứng dụng từ danh sách, Server gởi yêu cầu đến
máy khách. Máy khách nhận thông điệp sẽ tắt ứng dụng.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.18 Manage Service Use Case:
Tên Use Case: Manage Service.
Mô tả : Cho phép người quản lý có thể biết được các service chạy trên máy
khách, và người quản lý cũng có thể thay đổi loại khởi động( Automatic,
Manual hay Disable) hay cũng có thể thay đổi trạng thái service( Start hay
Stop).
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý yêu cầu quản lý dịch
vụ trên máy khách.
+ Người quản lý chọn máy khách mà người quản lý muốn
xem thông tin service.
+ Nếu người quản lý chọn xem danh sách các dịch vụ:
Server gởi thông điệp yêu cầu danh sách đến máy khách,
máy khách thực hiện việc ghi lại danh sách các dịch vụ
đang chạy ở máy khách và gởi về Server.
26
+ Nếu người quản lý chọn thay đổi loại khởi động dịch vụ:
màn hình yêu cầu nhập loại tương ứng để thay đổi. Server
gởi yêu cầu đến máy khách. Máy khách nhận thông điệp sẽ
thay đổi tương ứng.
+ Nếu người quản lý chọn thay đổi trạng thái dịch vụ: màn
hình yêu cầu chọn trạng thái tương ứng để thay đổi. Server
gởi yêu cầu đến máy khách. Máy khách nhận thông điệp sẽ
thay đổi tương ứng.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.19 Send Message Use Case:
Tên Use Case: Send Message.
Mô tả : Cho phép người quản lý có thể gởi tin nhắn đến một máy khách bất
kỳ hay cho tất cả các máy..
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý yêu cầu gởi tin nhắn.
+ Gởi đến một máy: người quản lý chọn máy khách mà
người quản lý muốn gởi thông điệp.
+ Nhập thông điệp và yêu cầu Server gởi thông điệp đến
máy đã chọn.
27
+ Gởi đến tất cả các máy: yêu cầu Server gởi thông điệp
đến tất cả các máy.
+ Máy khách nhận thông điệp sẽ xuất ra màn hình.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.20 Manage Remote Computer:
Tên Use Case: Manage Remote Computer.
Mô tả : Cho phép người quản lý có thể Logout, Restart hay Shutdown một
máy khách bất kỳ hay cho tất cả các máy.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người quản lý yêu cầu Logout,
Restart hay Shutdown.
+ Nếu người quản lý yêu cầu Logout: luồng sự kiện phụ
yêu cầu Logout được kích hoạt.
+ Nếu người quản lý yêu cầu Resstart: luồng sự kiện phụ
yêu cầu Resstart được kích hoạt.
+ Nếu người quản lý yêu cầu Shutdown: luồng sự kiện phụ
yêu cầu Shutdown được kích hoạt.
Logout:
+ Người quản lý có thể chọn một máy hay
tất cả máy.
28
+ Người quản lý có thể nhập thời gian.
Sau thời gian đó chương trình sẽ thực hiện
logout.
+ Người quản lý yêu cầu Logout. Server
sẽ gởi thông điệp đến máy khách yêu cầu
máy khách thực hiện logout.
tương tự cho Restart và Shutdown
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
+ Không có.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.1.21 SnapShot Use Case:
Xem phần kỹ thuật.
2.2.2.2
Phía Client:
2.2.2.2.1 Screen
2.2.2.2.1.1
Screen Connect Use Case:
Tên Use Case : Screen Connect.
Mô tả : Máy khách thực hiện kết nối với Server để vào trạng thái chờ.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi máy khách bắt đầu chạy chương trình.
29
+ Chương trình kiểm tra thông tin kết nối và gởi thông điệp
đến Server.
+ Nếu nhận được hồi đáp chấp nhận thì chương trình sẽ thực
hiện kết nối với Server và màn hình chờ bật lên( Use Case
thành công).
- Dòng sự kiện khác:
+ Nếu các thông tin kết nối không có ( như thông tin về tên
máy, địa chỉ IP SERVER, port ) thì sẽ nhập thông báo yêu cầu
nhập thông tin lại.
+ Nếu tên máy trùng với một tên máy đã kết nối trước vào
Server( do hồi đáp không chấp nhận của Server) thì cũng sẽ
nhập thông báo yêu cầu nhập thông tin lại.
+ Nếu kết nối không thành công thì sẽ báo lỗi.
- Điều kiện tiên quyết:
+ Server phải khởi động trước khi máy khách muốn kết nối vào
màn hình chờ.
- Hậu điều kiện:
+ Máy khách đang ở trạng thái down chuyển sang trạng thái
chờ.
- Điểm mở rộng:
+ Không có.
2.2.2.2.1.2 Login Member Use Case:
Tên Use Case : Login Member.
Mô tả: Máy khách thực hiện login vào Server dưới hình thức Member.
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi khách hàng bắt đầu đăng nhập vào
Server để sử dụng máy.
+ Khách hàng nhập thông tin bao gồm Username và Password.
30
+ Chương trình gởi thông điệp đến Server.
+ Nếu nhận được hồi đáp chấp nhận thì màn hình chờ tắt,
chương trình chính Client sẽ bật lên để tính giờ và khi đó
khách hàng có thể sử dụng được máy này.
- Dòng sự kiện khác:
+ Nếu nhận được hồi đáp từ chối thì màn hình screen vẫn
không bị tắt.
- Điều kiện tiên quyết:
+ Server phải khởi động trước.
+ Máy khách đang ở trạng thái chờ.
- Hậu điều kiện:
+ Máy khách đang ở trạng thái chờ chuyển sang trạng thái sử
dụng.
- Điểm mở rộng:
+ Không có.
2.2.2.2.2 Client
2.2.2.2.2.1 Client Connect Use Case:
Tên Use Case : Client Connect.
Mô tả: Máy khách thực hiện kết nối với Server để vào trạng thái sử dụng
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi người dùng login thành công vào
Server.
+ Chương trình kết nối với Server.
+ Server nhận được thông điệp kết nối sẽ bắt đầu gởi danh sách
các món ăn, banner cho Client.
+ Máy khách sẽ nhận thông điệp từ Server sẽ lưu trữ các thông
tin đó.
31
+ Máy khách xuất thông báo về nội quy sử dụng phòng máy.
- Dòng sự kiện khác:
+ Nếu kết nối không thành công thì sau 1 khoảng thời gian
máy khách sẽ tự động thực hiện kết nối lại với Server.
- Điều kiện tiên quyết:
+ Server phải khởi động trước khi máy khách muốn kết nối vào
màn hình chờ.
+ Máy khách đang ở trạng thái chờ.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.2.2.2.2 Order Use Case:
Tên Use Case : Order
Mô tả : Khách hàng có thể thực hiện đặt món ăn từ danh sách với Server
Dòng sự kiện :
- Dòng sự kiện chính :
+ Use case bắt đầu khi khách hàng yêu cầu phục vụ.
+ Danh sách các thức ăn, thức uống sẽ xuất hiện.
+ Khách hàng chọn các thông tin cần thiết như món ăn, số
lượng…
+ Khi khách hàng yêu cầu phục vụ các món mình đã chọn thì
máy khách sẽ gởi thông điệp cho Server.
+ Server nhận thông điệp sẽ lần lượt phục vụ các món ăn khách
hàng đã yêu cầu.
- Dòng sự kiện khác:
+ Không có.
- Điều kiện tiên quyết:
32
+ Server phải khởi động trước khi máy khách muốn kết nối vào
màn hình chờ.
+ Phía máy khách đang ở trong trạng thái sử dụng.
- Hậu điều kiện:
+ Không có.
- Điểm mở rộng:
+ Không có.
2.2.3 Thiết kế lớp trên Server:
2.2.3.1 Giao diện Server:
33
l
l
l
l
l
g D
l
l
g D
l
l
l
g D e c
g D
g D e u
l
t i
i r
i
g D h s a r
t
t r o p e R y
t
l i
C r e
b e D C
I
t f
g D r e n n a B C
t r o p e R h t n o M C
P u p n C
I
g D h s D t u p n I C
g D r e v r e S o f n I C
a V t u p n I C
a D C
A C
r e b m e M u p n C
g D y r o g e t a C t u p n I C
l
g D
t r o p e R
t i
b e D C
b a T n o i t a t S k r o W C
l
g D
l
t r o p e R
l i
a
t
e D
t i
i
g D r e v r e S e f a C C
b e D C
b a T e c v r e S C
i
b a T n m d A C
L S S e g a P b a T C
e g a P b a T t n e r a P C
b a T
i
t s L v r
S C
l r t
C b a T e s a B C
l
l
l r t
L S S
b a T
t
l r t
b a T g n
t s
i
i l
g D p u t r a S v r
C b a T n E C
p p A C
b a T g o L y e K C
b a T p a C r c S C
C b a T C
b a T k c o L y e K C
g g o L C
b a T e g a s s e M C
g D s u t a t S v r S g h C C
S g h C C
l
g D d d A y e K k c o L C
Hình 2-7 Thiết kế lớp giao diện Server
34
STT Tên lớp Kế thừa từ lớp Chức năng
dùng tự vẽ giao diện
1 CBaseTabCtrl CTabCtrl tab ctrl
dùng tô màu đỉnh Tab
theo màu nền 2 CEnTabCtrl CBaseTabCtrl
dùng Add Dialog (xem
1 dialog như một trang
của tab) 3 CTabCtrlSSL CEnTabCtrl
dùng để thể hiện
dialog như một trang
của Tab 4 CTabPageSSL CDialog
dùng để tô màu nền
5 CParentTabPage CTabPageSSL và gắn tooltip
giao diện để điều
khiển hoạt động máy
tính 6 CLoggingTab CParentTabPage
giao diện để khóa bàn
phím 7 CKeyLockTab CParentTabPage
giao diện dùng để ghi
8 CKeyLogTab CParentTabPage phím
giao diện dùng để cho
người dùng nhập các
phím cần khóa 9 CLockKeyAddDlg CParentTabPage
giao diện dùng để
người quản lý gởi tin
nhắn đến một máy 10 CMessageTab CParentTabPage
35
hay nhiều máy
giao diện dùng để
11 CScrCapTab CParentTabPage chụp màn hình
giao diện dùng để
quản lý các ứng dụng
phía máy khách 12 CApplistTab CParentTabPage
giao diện dùng để
quản lý phục vụ các
dịch vụ như món ăn,
thức uống cho khách
hàng 13 CServiceTab CParentTabPage
nhập dữ liệu về trạng
thái hoạt động của
dịch vụ 14 CChgSrvStartupDlg CDialog
nhập dữ liệu về trạng
thái khởi động của
dịch vụ 15 CChgSrvStatusDlg CDialog
giao diện dùng để
quản lý các service
phía máy khách 16 CSrvListTab CParentTabPage
dùng để chứa các
giao diện quản trị 17 CAdminTab CParentTabPage
dùng để quản lý việc
tính cước, giá cả các
dịch vụ kèm theo 18 CWorkStationTab CParentTabPage
dùng quản lý chương
trình sau khi có một
client bị đứt kế nối 19 CAfterCrashDlg CDialog
20 CBannerDlg CDialog giao diện dùng nhập
36
banner, rồi xuất các
quy định ở máy khách
giao diện dùng nhập
các thông tin về
Server lúc bắt đầu 21 CInfoServerDlg CDialog
giao diện dùng quản lý
loại thức ăn, nước
uống 22 CInputCategoryDlg CDialog
giao diện dùng quản lý
các món ăn, thức
uống 23 CInputDishDlg CDialog
giao diện dùng quản lý
24 CInputMemberDlg CDialog thanh viên tham gia
giao diện dùng quản lý
25 CDebitDlg CDialog các khách hàng nợ
giao diện dùng quản lý
giá cả các ngày 26 CInputPriceDlg CDialog
giao diện dùng nhập
27 CInputValueDlg CDialog giá cả của ngày
giao diện dùng thống
kê các đăng nhập sử
dụng của khách hàng 28 CDailyReportDlg CDialog
giao diện dùng thống
kê số tiền máy khách
kiếm được trong một
tháng 29 CMonthReport CDialog
giao diện dùng thống
30 CDebitReportDlg CDialog kê các khách hàng nợ
31 CdebitDetail- CDialog giao diện dùng xuất
37
ReportDlg chi tiết về một khách
hàng nợ
giao diện chương
trình Server 32 CCafeServerDlg CDialog
2.2.3.2
Xử lý Server:
CInputPriceDay
CSolveMember
CInputDish
CSolveCategory
CInputCategory
CSolveDish
CSolveDailyReport
CSolveLogin
CCafeDB
CSolveMonthReport
CSolveFee
CSolveDebitList
CSolveTableFee
CSolveDebitDetail
CSolveFeeDay
CADODatabase
CADORecordSet
CADOCommand
CADOFieldInfo
CADOParameter
CADOException
Hình 2-8 Thiết kế lớp xử lý Server
38
STT Tên lớp Kế thừa từ lớp Chức năng
Lớp xử lý việc quản
1 CSolveMember CCafeDB lý các thành viên
Lớp xử lý việc quản
lý các loại món ăn,
thức uống 2 CSolveCategory CCafeDB
Lớp xử lý việc quản
lý các món ăn, thức
uống 3 CSolveDish CCafeDB
Lớp xử lý việc quản
lý Login,Logout 4 CSolveLogin CCafeDB
Lớp xử lý việc tính
5 CSolveFee CCafeDB tiền
Lớp xử lý việc quản
6 CSolveTableFee CCafeDB lý tiền phí
Lớp xử lý việc quản
7 CSolveFeeDay CCafeDB lý tiền phí
Lớp xử lý việc quản
lý giá cả 8 CInputPriceDay CCafeDB
Lớp xử lý việc quản
9 CInputDish CCafeDB lý món ăn,thức uống
Lớp xử lý việc quản
10 CInputCategory CCafeDB lý loại món ăn
Lớp xử lý việc báo
11 CSolveDailyReport CCafeDB cáo hàng ngày
Lớp xử lý việc báo
12 CSolveMonthReport CCafeDB cáo theo tháng
13 CSolveDebitList CCafeDB Lớp xử lý việc nợ
39
của các thành viên
Lớp xử lý việc nợ
của các thành viên
một cách chi tiết 14 CSolveDebitDetail CCafeDB
15 CADODatabase CADOCommand
16 CADORecordset CADOCommand, CADOFieldInfo
17 CADOCommand CADOParameter
18 CADOFieldInfo
19 CADOParameter
20 CADOException
2.2.4 Thiết kế lớp trên Client:
2.2.4.1
Screen:
CBlockingSocketException
CSockAddr
CBlockingSocket
CInfoPcDlg
CScreenDlg
CLogonDlg
Hình 2-9 Thiết kế lớp Screen
Kế thừa từ
STT Tên lớp lớp Chức năng
Chỉ địa chỉ IP, thông tin Port
1 CSockAddr sockaddr_in dịch vụ
40
Nó thay thế lớp Socket của
MFC. Đây là lớp giữ chức
năng quan trọng nhất trong
chương trình vì nó có thể
thiết lập, tiếp nhận kết nối và
quản lý việc truyền dữ liệu. 2 CBlockingSocket CObject
Lớp quản lý lỗi cho việc thiết
lập, tiếp nhận kết nối và quản CblockingSocket-
lý việc truyền dữ liệu. 3 Exception CException
Dùng để nhập thông tin khi
không có thông tin kết nối 4 CInfoPcDlg
Dùng để nhập thông tin
Logon 5 CLogonDlg
Giao diện che màn hình
không cho khách hàng sử
dụng máy khách 6 CScreenDlg
2.2.4.2
Client:
CCafeClientDlg
COrder
CKeyLogClient
CKeyLockCLient
CTaskMgr
CShutdownClient
CKeyClient
CSockAddr
CBlockingSoket
CBlockingSocketException
Hình 2-10 Thiết kế lớp Client
41
Kế thừa từ
STT Tên lớp lớp Chức năng
Chỉ địa chỉ IP, thông tin
Port dịch vụ 1 CSockAddr sockaddr_in
Nó thay thế lớp Socket
của MFC. Đây là lớp giữ
chức năng quan trọng
nhất trong chương trình vì
nó có thể thiết lập, tiếp
nhận kết nối và quản lý
việc truyền dữ liệu. 2 CBlockingSocket CObject
Lớp quản lý lỗi cho việc
thiết lập, tiếp nhận kết nối
và quản lý việc truyền dữ CblockingSocket-
liệu. 3 Exception CException
Lớp quản lý lỗi cho việc
4 CKeyClient Lock hay Log key
Giao diện phục vụ việc
đặt món ăn của khách
hàng 5 COrder CDialog
6 CKeyLockClient CKeyClient Lớp xử lý khóa phím
Lớp xử lý ghi nhận phím
7 CKeyLogClient CKeyClient sử dụng
Giao diện chính của
8 CCafeClientDlg chương trình Client
42
2.2.5 Hiện thực hóa Use Case:
2.2.5.1
Use case Start Server:
: User
Object1 : CCafeServerDlg
Object2 : CBlockingSocket
1: StartServer( )
2: CreateConnection( )
3: StartListenConnection( )
Hình 2-11 Sequence Diagram Start Server
43
2.2.5.2
Use case Login:
l
g D t n e
i l
C e f a C C
j
: 7 t c e b O
) ( t c e n n o C
: 8
: ) t n e
i l
t e k c o S g n
i
l
l
j
C ( 6 t c e b O
k c o B C
l
l
l
u f s s e c c u S e s o C
) ( e s o C
:
7
g D n e e r c S C
:
5
j
) ( n o i t a c
i l
t c e b O
t
) ( e g a s s e M d n e S
l
:
p p A e s o C
9
: 5
e k c o S g n
i
: ) n e e r c S ( 4
j
l
k c o B C
) ( n o
t c e b O C
t
) ( e g a s s e M d n e S
) ( e g a s s e M d n e S
t
: 4
: 6
e k c o S g n
i
: ) r e v r e S ( 3
i t c e n n o C p e c c A
:
l
j
0 1
k c o B C
t c e b O
i
l
n g o L e v o S C
:
2
) ( o f n I t e S
j
: 3
t c e b O
) ( e s a b a t a D k c e h C
b a T n o i t a t
: 2
S k r o W C
j
: 1 t c e b O
i
) ( r e t u p m o C n g o L : 1
r e s U
:
Hình 2-12 Sequence Diagram Login
44
2.2.5.3
Use case Logout:
l
) ( n o
t
g D n e
i l
C e
f
l
a C C
i t c e n n o C e s o C
:
:
) ( n o
8
8
t c e
j
b O
t
: ) t
l
i t c e n n o C e s o C
n e
:
i l
7
) ( n e e r c S
t r a t
e k c o S g n ki c o
C ( 7 t c e
l
j
S
B C
: 9
b O
l
g D n e e r c S C
) ( n o
: 6 t c e
j
b O
i t c e n n o C
) ( e g a s s e M d n e S
t
:
t r a S
6
:
0 1
: ) n e e r c S
t e k c o S g n ki c o
l
( 5 t c e
j
B C
b O
) ( n o
) ( e g a s s e M d n e S
: 1 1
: ) r e v r e S
i t c e n n o C t p e c c A
t e k c o S g n ki c o
( 4 t c e
l
j
: 2 1
B C
b O
t r o p e R y
l i
: 3 t c e
j
a D e v
b O
l
) ( o
f
n
I t
o S C
n e
i l
n
i
o f n I t n e
i l
C e v a S
:
g o L e v
l
3
C e t e
l
o S C
) ( r e t u p m o C t u o g o L : 5
e D
: 4
) ( n
i
: 2 t c e
j
b O
g o L o
f
n
I
e
t
e
l
b a T n o
e D
: 2
i t a t S k r o W C
: 1 t c e
j
b O
r e s U
) ( r e t u p m o C t u o g o L : 1
:
Hình 2-13 Sequence Diagram Logout
45
2.2.5.4
Use case Paid
: ) r e v r e S
i
( 7 t c e
l
j
t e k c o S g n k c o B C
b O
e e F e
l
: 6 t c e
j
b a T e v
l
b O
o S C
) ( e
l
b a T
t
e G
:
5
y a D e e F e v
l
o S C
) ( y a D t e S
: 4
: 5 t c e
j
b O
) ( e c
i r
P
t e G
: 6
) ( e e F e
t
e e F e v
l
o S C
u p m o C
:
7
: 4 t c e
j
) ( r e t u p m o C
b O
t u o g o L : 2 1
t r o p e R y
l i
) ( e e F
: 3 t c e
j
t e G
a D e v
b O
l
: 8
) ( e e F r e t u p m o C
o S C
: 3
) ( o f n I t n e
i l
n
C e v a S
i
: 9
) ( o f n I t n e
i l
g o L e v
l
C e t e
l
o S C
e D
: 1 1
: 2 t c e
j
b O
) ( e e F
: 0 1
) ( e e F r e t u p m o C
: 2
b a T n o
i t a t S k r o W C
) ( r e
t
: 1 t c e
j
b O
u p m o C d
i
a P
:
1
r e s U
:
Hình 2-14 Sequence Diagram Paid
46
2.2.5.5
Use Case SetBanner:
Object2 : CCafeClientDlg
: User Object1 : CCafeServerDlg Object2(Server) : CBlockingSocket
Object3(Client) : CBlockingSocket
1: EnterBanner( )
2: SetBanner( )
3: SendMessage( )
4: GetBanner( )
5: ShowBanner( )
Hình 2-15 Sequence Diagram SetBanner
2.2.5.6
Use Case Service Order
: User
Object1 : CServiceTab Object2 : CMyHFlexGrid
Object2 : CWorkStationTab
Object3 : CSolveLoginService
1: ServeDish( )
2: ShowInfo( )
3: UpdateServiceFee( )
4: SaveToDatabase( )
Hình 2-16 Sequence Diagram Service Order
2.2.5.7
Use case Daily Report
47
: User
Object1 : CDailyReportDlg
Object2 : CDailyReportFlexGrid
Object3 : CSolveDailyReport
1: DailyReport( )
2: OpenDatabase( )
3: GetAllInfo( )
4: ShowReport( )
Hình 2-17 Sequence Diagram Daily Report
48
2.2.5.8
Use case Debit Report:
t r o p e R
l i
a t e D
j
: 6 t c e b O
l
t i b e D e v o S C
) ( o f n I l l
d i r
A t e G
) ( l i
t
l
: 8
:
5
a e D w o h S
G x e F t r o p e R
j
l i
:
9
t
t c e b O
a e D
t i
) ( e s a b a t a d n e p O
: 7
b e D C
l
g D
t r o p e R
l i
a t e D
t i b e D C
j
: 4 t c e b O
f
i
) ( o n
j
t
l
: 3 t c e b O
I t r o p e R e S
:
t s L t i b e D e v o S C
6
f
) ( o n
I l l
d i r
t
A e G
l
:
) 3
G x e F t r o p e R
) ( t r o p e R w o h S
: 4
t i b e D C
( e s a b a t a D n e p O
: 2
j
: 2 t c e b O
l
) ( l i
g D
a t e D
t r o p e R
t i
t r o p e R
: 5
b e D C
:
1
j
) ( t r o p e R
t c e b O
t i b e D
: 1
r e s U
:
Hình 2-18 Sequence Diagram Debit Report
49
2.2.5.9
Use case Month Report
: User
Object1 : CMonthReportDlg
Object2 : CMSFlexGrid
Object3 : CSolveMonthReport
1: MonthReport( )
2: OpenDatabase( )
3: GetAllInfo( )
4: ShowReport( )
Hình 2-19 Sequence Diagram Month Report
2.2.5.10 Use case Manage Cafeteria:
Object3 : CInputCategory
: User
Object1 : CInputCategoryDlg
Object2 : CCategoryListFlexGrid
1: Category( )
2: OpenDatabase( )
3: GetAllInfo( )
4: ShowCategory( )
2.2.5.10.1 Show:
Hình 2-20 Sequence Diagram Manage Cafeteria Show
50
: User
Object1 : CInputCategoryDlg Object3 : CInputCategory
Add new Category
1: EnterNewInfo( )
2: Add( )
3: SetInfo( )
4: Save( )
2.2.5.10.2 Add:
Hình 2-21 Sequence Diagram Manage Cafeteria Add
Object1 : CInputCategoryDlg
Object2 : CCategoryListFlexGrid Object3 : CInputCategory
: User
1: ChooseCategory( )
2: Edit( )
3: UpdateInfo( )
4: Update( )
2.2.5.10.3 Edit
Hình 2-22 Sequence Diagram Manage Cafeteria Edit
51
Object3 : CInputCategory
Object2 : CCategoryListFlexGrid
: User
Object1 : CInputCategoryDlg
1: ChooseCategory( )
2: Delete( )
3: DeleteCategory( )
4: Delete( )
2.2.5.10.4 Delete:
Hình 2-23 Sequence Diagram Manage Cafeteria Delete
2.2.5.11 Use case Manage Debit
2.2.5.11.1 Add
52
l i
a t e D
t i
) ( e v a s : 9
: 5 t c e
j
b e D e v
b O
l
o S C
t s
i
L t i
) ( e v a S
: 6
: 4 t c e
j
b e D e v
l
b O
o S C
t r o p e R y
l i
: 3 t c e
) ( o f n I l i
j
a D e v
b O
l
o S C
a t e D t e S
l
i
: 8
g D
t i
) ( o f n I c s a B
t e S
b e D C
) ( o f n I l i
: 5
: 2 t c e
j
) (
b O
a t e D t e G
: 7
) ( o f n I n o s r e P
l
l l
n o s r e P
g D
A
m r o F n e p O
t i
: 2
t e G
) ( o
f
b e D
w e n d d A
: 4
n I r e
t
n E
r e v r e S e f a C C
:
3
: 1 t c e
j
) ( t i
b O
b e D
: 1
r e s U
:
Hình 2-24 Sequence Diagram Debit Add
53
l i
a t e D
) ( e v a s : 2 1
j
l
: 5 t c e b O
t i b e D e v o S C
i
) ( e v a S
l
: 0 1
t s L t i b e D e v o S C
) ( o f n I l i
) ( o f n I l i
) ( o f n I l i
j
a t
: 4 t c e b O
t
a t e D t e S
e D t e S
a t e D e G
:
: 5
6
: 1 1
) ( o f n I c
) ( o f n I c
) ( o f n I c
i
i
i
t r o p e R y
l i
j
s a B t e S
s a B t e S
s a B t e G
l
: 3 t c e b O
: 9
: 3
: 4
a D e v o S C
l
g D
) ( o f n I w o h S
t i b e D C
: 7
j
: 2 t c e b O
l
) ( o f n I c
i
) ( t i
d E
:
g D r e v r e S e f a C C
8
s a B r e t n E
:
j
: 1 t c e b O
) 2 ( t i b e D
: 1
r e s U
:
Hình 2-25 Sequence Diagram Manage Debit Edit
54
2.2.5.12 Use case Manage Kind of Food:
: User Object1 : CInputDishDlg Object2 : CDishListFlexGrid Object3 : CInputDish
1: Dish( )
2: OpenDatabase( )
3: GetAllInfo( )
4: ShowDish( )
Add new Dish
5: EnterNewInfo( )
6: Add( )
7: SetInfo( )
8: Save( )
2.2.5.12.1 Add
Hình 2-26 Sequence Diagram Manage Kind of Food Add
2.2.5.12.2 Edit
55
: User Object1 : CInputDishDlg Object2 : CDishListFlexGrid Object3 : CInputDish
1: Dish( )
2: OpenDatabase( )
3: GetAllInfo( )
4: ShowDish( )
5: ChooseDish( )
6: Edit( )
7: UpdateInfo( )
8: Update( )
Hình 2-27 Sequence Diagram Manage Kind of Food Edit
2.2.5.12.3 Delete
56
: User Object1 : CInputDishDlg Object2 : CDishListFlexGrid Object3 : CInputDish
1: Dish( )
2: OpenDatabase( )
3: GetAllInfo( )
4: ShowDish( )
5: ChooseDish( )
6: Delete( )
7: DeleteDish( )
8: Delete( )
Hình 2-28 Sequence Diagram Manage Kind of Food Delete
2.2.5.13 Use case Manage Member:
2.2.5.13.1 Add
57
: User
Object1 : CInputMemberDlg Object2 : CMemberFlexGridObject3 : CSolveMember
1: Member( )
2: OpenDatabase( )
3: GetInfo( )
4: ShowMember( )
Add Member
5: EnterInformation( )
6: Add( )
7: SetInfo( )
8: Save( )
Hình 2-29 Sequence Diagram Manage Member Add
2.2.5.13.2 Edit
58
: User
Object1 : CInputMemberDlg Object2 : CMemberFlexGridObject3 : CSolveMember
1: Member( )
2: OpenDatabase( )
3: GetInfo( )
4: ShowMember( )
Edit Member
5: ChooseMember( )
6: Edit( )
7: SetInfo( )
8: Update( )
Hình 2-30 Sequence Diagram Manage Member Edit
2.2.5.13.3 Delete
59
: User
Object1 : CInputMemberDlg Object2 : CMemberFlexGridObject3 : CSolveMember
1: Member( )
2: OpenDatabase( )
3: GetInfo( )
4: ShowMember( )
Delete Member
5: ChooseMember( )
6: Delete( )
7: SetInfo( )
8: Update( )
Hình 2-31 Sequence Diagram Manage Member Delete
60
2.2.5.14 Use case Manage Price Day:
: 6 t c e
j
l
b O
y a D e e F e v o S C
l
l
l
) ( y a D e e F t e S
: 7 1
j
l
l
: 5 t c e b O
) ( e b a T o f n I t e S
: 5
e b a T e e F e v o S C
) ( e b a T o f n I m o r F y a D e e F t e G
) ( y a D t e S
: 6
: 3
) ( e b a T o f n I t e G
: 4
y a D e c i r
j
: 4 t c e b O
P t u p n I C
y a D e c i r
P e u
l
) ( o f n I l l
l
a V t u p n I C
A t e G
: 7
) (
j
l
) ( e b a T o f n I t e S
: 3 t c e b O
t
: 6 1
) ( e u a V e G
m r o F n e p O
:
4 1
) ( e c i r
d i r
: 2 1
) ( e s a b a t a D n e p O
l
: 2
) ( y a D e c i r
G x e F
i
: 2 t c e
j
P w e N w o h S
P w o h S
:
b O
: 8
5 1
l
t s L y a D e c i r
) ( e u a V
P C
r e t n E
: 3 1
l
i
g D y a D e c i r
) ( o f n I w e N r e t n E
:
) ( e m T & y a D e s o o h C
1 1
P t u p n I C
: 9
y a D
f
) ( t i
j
d E
:
) ( y a D e c i r
: 1 t c e b O
O e c i r
P
0 1
P
: 1
t i
d E
r e s U
:
Hình 2-32 Sequence Diagram Manage Price Day
61
2.2.5.15 Use case Lock Key:
t
n e
i l
C k c o L y e K C
:
5
l
j
t c e b O
l
t
) ( y e K k c o L : 6
g D n e
i l
u f s s e c c u S k c o L
f
C e a C C
j
f
) ( o n
: 4 t c e b O
I t
) ( o f n I t e S
e G
:
: 7
5
: ) t n e
i l
i
l
j
C ( 3 t c e b O
t e k c o S g n k c o B C
) ( e g a s s e M d n e S
) ( e g a s s e M d n e S
: 8
: 4
t e k c o S g n
i
l
j
k c o B C
: ) r e v r e S ( 2 t c e b O
f
) ( o n
I t
l
e S
:
3
) ( e g a s s e M w o h S
: 9
g D r e v r e S e f a C C
j
) ( k c o L y e K
: 1 t c e b O
t
t r a S
:
2
) ( k c o L e d o M e h t e s o o h C
r e s U
: 1
:
Hình 2-33 Sequence Diagram Lock Key
62
2.2.5.16 Use case Log Key
t
n e
i l
C g o L y e K C
:
5
l
j
t c e b O
l
t
) ( y e K g o L : 5
g D n e
i l
u f s s e c c u S g o L
f
C e a C C
j
: 4 t c e b O
) ( o f n I t e S
) ( o f n I t e G
: 6
: 4
: ) t n e
i l
t e k c o S g n
i
l
j
C ( 3 t c e b O
k c o B C
) ( e g a s s e M d n e S
) ( e g a s s e M d n e S
:
: 7
3
t e k c o S g n
i
l
j
k c o B C
: ) r e v r e S ( 2 t c e b O
l
) ( o f n I t e S
: 2
) ( e g a s s e M w o h S
:
8
g D r e v r e S e f a C C
j
) ( g o L y e K
: 1 t c e b O
t
t r a S
:
1
r e s U
:
Hình 2-34 Sequence Diagram Log Key
63
2.2.5.17 Use case Message:
: User
Object : CMessageTab Object : CBlockingSocket Object : CBlockingSocket Object : CCafeClientDlg
1: ChooseComputer( )
2: EnterMesage( )
3: SetInfo( )
4: SendMessage( )
5: GetInfo( )
6: ShowMessage( )
Hình 2-35 Sequence Diagram Send Message
2.2.5.18 Use case Manage Remote Computer
: User
Object : CLoggingtab
Object : CCafeClientDlg Object : CShutDownClient
Object(Server) : CBlockingSocket
Object(Client) : CBlockingSocket
1: SetOption
2: Shutdown
3: SetInfo( )
4: SendMessage( )
5: GetInfo( )
6: Shutdown( )
7: Shutdown( )
Hình 2-36 Sequence Diagram Manage Remote Computer
64
2.2.5.19 Use case Manage Application:
Object4 : CCafeClientDlg Object5 : CTaskMgr
: User Object1 : CAppListtab Object2(Server) : CBlockingSocket
Object3(Client) : CBlockingSocket
1: SetComputer( )
2: ListAll( )
3: SetInfo( )
4: SendMessage( )
5: GetInfo( )
6: RequestList( )
7: GetWindowList( )
8: SetInfo( )
9: SendMessage( )
10: GetInfo( )
2.2.5.19.1 List:
Hình 2-37 Sequence Diagram Manage Application - List
2.2.5.19.2 Start:
65
) ( p p A
t
t r a S
r g M k s a T C
:
8
j
: 5 t c e b O
) ( p p A
l
t r a t
S
) ( t l u s e R t e G
g D t n e
: 7
: 9
i l
C e f a C C
f
j
) ( o n
I t
: 4 t c e b O
e S
) ( o f n I t e G
:
6
: 0 1
: ) t n e
i l
t e k c o S g n
i
j
l
C ( 3 t c e b O
k c o B C
) ( e g a s s e M d n e S
) ( e g a s s e M d n e S
: 5
: 1 1
t e k c o S g n
i
) ( t l
l
j
k c o B C
: ) r e v r e S ( 2 t c e b O
) ( o f n I t e S
u s e R w o h S
i
: 4
:
2 1
b a t t s L p p A C
j
) ( p p A
: 1 t c e b O
t r a t
) ( o f n I r e t n E
S
) ( r e t u p m o C t e S
: 3
: 2
: 1
r e s U
:
Hình 2-38 Sequence Diagram Manage Application - Start
66
Object4 : CCafeClientDlg Object5 : CTaskMgr
: User Object1 : CAppListtab Object2(Server) : CBlockingSocket
Object3(Client) : CBlockingSocket
1: SetComputer( )
2: ChooseApp( )
3: StopApp( )
4: SetInfo( )
5: SendMessage( )
6: GetInfo( )
7: StopApp( )
8: StopApp( )
9: GetResult( )
10: SetInfo( )
11: SendMessage( )
12: ShowResult( )
2.2.5.19.3 Stop:
Hình 2-39 Sequence Diagram Manage Application – Stop
2.2.5.20 Use case Manage Service:
2.2.5.20.1 Show List
67
Object7 : CTaskMgr
Object6 : CCafeClientDlg
: User
Object1 : CSrvListtab Object4(Server) : CBlockingSocket
Object5(Client) : CBlockingSocket
1: SetComputer( )
2: ListAll( )
3: SetInfo( )
4: SendMessage( )
5: GetInfo( )
6: RequestServiceList( )
7: GetServiceList( )
8: SetInfo( )
9: SendMessage( )
10: GetInfo( )
11: ShowList( )
Hình 2-40 Sequence Diagram Manage Service – Show List
68
) ( p u t r a
t
r g M k s a T C
S e g n a h C
:
9
j
) ( t l
: 7 t c e b O
) ( p u t r a t
t
l
u s e R e G
:
S e g n a h C
g D t n e
0 1
i l
: 8
C e f a C C
j
f
) ( o f n
: 6 t c e b O
I t e S
) ( o n I t e G
t
: 7
: 1 1
: ) t n e
i l
e k c o S g n
i
C ( 5
j
l
t c e b O
k c o B C
t
) ( e g a s s e M d n e S
) ( e g a s s e M d n e S
:
6
: 2 1
e k c o S g n
i
: ) r e v r e S ( 4
l
j
k c o B C
t c e b O
l
g D p u
t r a
t
S v r
f
) ( o n
I t
e S
S g h C C
:
) ( t l u s e R w o h S
:
5
2
: 3 1
j
l
t c e b O
) ( e
l
) ( e y t S t e G
: 4
b a
y t S p u t r a
i
t
t t s L v r S C
S e s o o h C
i
:
3
j
: 1 t c e b O
) ( r e t u p m o C t e S
) ( e c v r e S e s o o h C
: 1
: 2
r e s U
:
ChangeStartupService:
Hình 2-41 Sequence Diagram Manage Service – Change Startup Service
69
) ( s u t a t
r g M k s a T C
S e g n a h C
:
j
: 7 t c e b O
t
l
) ( t l u s e R e G
:
) 9 ( s u t a t S e g n a h C
g D t n e
0 1
i l
: 8
C e f a C C
j
f
: 6 t c e b O
) ( o n I t e S
) ( o f n I t e G
: 7
: 1 1
: ) t n e
i l
t e k c o S g n
i
l
j
C ( 5 t c e b O
k c o B C
) ( e g a s s e M d n e S
) ( e g a s s e M d n e S
:
: 6
2 1
t e k c o S g n
i
l
j
k c o B C
: ) r e v r e S ( 4 t c e b O
l
g D s u t a t S v r
S g h C C
) ( o f n I t e S
) ( t l u s e R w o h S
: 5
: 3 1
j
l
: 3 t c e b O
l
) ( e y t
) ( e y t S t e G
: 4
t
i
b a t t s L v r
S C
:
1
S s u a t S e s o o h C
i
t
: 3
j
t c e b O
t
) ( r e u p m o C e S
) ( e c v r e S e s o o h C
:
1
: 2
r e s U
:
Change Status
Hình 2-42 Sequence Diagram Manage Service – Change Status
70
2.2.6 Thiết kế cơ sở dữ liệu
Category
STT
Tên
Thuộc tính
Mô tả
1 MALOAI
Số nguyên
2 TENLOAI
Text
tên lọai thức ăn, nước uống
Hình 2-43 Cơ sở dữ liệu
DailyReport
STT
Tên
Thuộc tính
Mô tả
1 PC_NO
Text
Giờ lúc khách hàng bắt đầu
2 START_TIME Ngày giờ
sử dụng máy
Giờ lúc khách hàng kết thúc
sử dụng máy
3 END_TIME
Ngày giờ
4 USERNAME
Text
tiền khi khách hàng sử dụng
các dịch vụ có liên quan
5 ORDER_FEE số thực
6 WS_FEE
số thực
tiền phí sử dụng máy
7 TOTAL_FEE
số thực
tổng phí
8
ID_SERVICE Text
Bảng 2-1 Category
DEBIT_DETAIL
STT
Tên
Thuộc tính
Mô tả
Bảng 2-2 Daily Report
71
1 ID_DEBIT
số nguyên
2 PC_NO
Text
3 USERNAME
Text
Giờ lúc khách hàng bắt
4 START_TIME Ngày giờ
đầu sử dụng máy
Giờ lúc khách hàng kết
thúc sử dụng máy
5 END_TIME
Ngày giờ
6 TOTAL_FEE
số thực
tổng phí
DEBIT_LIST
STT
Tên
Thuộc tính
Mô tả
1 ID
số nguyên
2 NAME
Text
Tên khách nợ
3 ADDRESS
Text
4 PHONE
Text
5 TOTAL_FEE
số thực
Tổng tền phải trả
Tiền khách có thể trả
6 PREPAY
số thực
trước
Bảng 2-3 Bảng Debit_Detail
DISH
STT
Tên
Thuộc tính
Mô tả
1 MA
số nguyên
2 DESCRIPTION Text
Tên món thức ăn
Loại thức ăn, nước
3 MALOAI
số nguyên
uống
4 PRICE
số thực
giá cả
Bảng 2-4 Debit List
FEE_DAY
STT
Tên
Thuộc tính
Mô tả
1 ID_TABLE
Text
2 BEGIN_TIME Ngày giờ
giờ bắt đầu
3 END_TIME
Ngày giờ
giờ kết thúc
4 FEE_HOUR
số thực
Bảng 2-5 Dish
Bảng 2-6 Fee-Day
72
LOGIN
STT
Tên
Thuộc tính
Mô tả
1 PC_NO
Text
2 USERNAME
Text
3 PASSWORD Text
4 START_TIME Ngày giờ
5 END_TIME
Ngày giờ
6 FEE
số thực
7 ID_SERVICE Text
LOGIN_SERVICE STT
Tên
Thuộc tính
Mô tả
1 ID
Text
2 MA_DISH
số nguyên
3 AMOUNT
số nguyên
Bảng 2-7 Login
MEMBER
STT
Tên
Thuộc tính
Mô tả
1 USERNAME Text
2 PASSWORD Text
3 ADDRESS
Text
4 TELEPHONE Text
5 FEE
số thực
6 PRIORITY
số nguyên
Bảng 2-8 Login Service
MONTH_REPORT
STT
Tên
Thuộc tính
Mô tả
1 DATE
Ngày giờ
2 PC_NO
Text
3 TOTAL_FEE
số thực
Bảng 2-9 Member
TABLE_DAY
STT
Tên
Thuộc tính
Mô tả
1 ID_TABLE
Text
2 DAY
Ngày giờ
Bảng 2-10 Month Report
Bảng 2-11 Table Day
73
2.2.7 Thiết kế màn hình :
2.2.7.1
Thiết kế màn hình trên Client:
2.2.7.1.1 Màn hình Screen:
Hình 2-44 Màn hình Screen
2.2.7.1.2 Màn hình Chính Client
74
Hình 2-45 Màn hình chính Client
Hình 2-46 Màn hình Order phí Client
2.2.7.2
Thiết kế màn hình trên Server:
2.2.7.2.1 Tab WorkStation:
75
Hình 2-47 Màn hình Server – WorkStation
2.2.7.2.2 Tab Service:
76
Hình 2-48 Màn hình Server – Service
2.2.7.2.3 Tab Administration:
Hình 2-49 Màn hình Server – Keylock
77
Hình 2-50 Màn hình Server – Keylog
Hình 2-51 Màn hình Server – Message
78
Hình 2-52 Màn hình Server – Apllication
Hình 2-53 Màn hình Server – Service
79
Hình 2-54 Màn hình Server – Snapshot
2.3 Cài đặt và thử nghiệm:
2.3.1 Cài đặt:
Ứng dụng Server và CafeClient được phát triển sử dụng các công cụ và môi
trường sau:
+ Công cụ phân tích và thiết kế: Rational Rose 2003
+ Môi trường cài đặt ứng dụng: Windows XP Professional
+ Môi trường lập trình: Microsoft Visual Studio 6.0
2.3.2 Thử nghiệm:
Chương trình được cài đặt thử nghiệm trên phòng máy của trung tâm mạng
STT Tính năng thử nghiệm
1 Kết nối
Đánh giá Tốt
Tính cước và các dịch vụ liên quan
2 3 Quản trị từ xa 4 Chụp màn hình tĩnh 5 Chụp màn hình động
6 Policy
Tốt Tốt Tốt Tốt Tùy thuộc vào thiết lập máy phía Client
Máy Tính Nhất Nghệ - đường Bà Huyện Thanh Quan - với kết quả như sau:.
80
Chương 3 Các kỹ thuật lập trình
3.1 Kỹ thuật lập trình sự kiện và hook
Trong quá trình thực hiện phần mềm, có một yêu cầu quản trị hệ thống là
người quản trị cần biết lúc này người dùng đang gõ nội dung gì trên bàn phím hoặc
anh ta có nhu cầu khóa tạm thời bàn phím hay một số phím nhất định. Các nhu cầu
đó dẫn đến tình huống cần một cơ chế quản lý và kiểm soát bàn phím. Trong hệ
thống Windows, có một cơ chế đáp ứng như thế : cơ chế hook.
3.1.1 Sự kiện và thông điệp trên HĐH Windows
Trước hết, ta phải hiểu thêm về cơ chế thông điệp của hệ điều hành
Windows. Đây là cơ chế cho phép các ứng dụng phân loại, lưu trữ, đáp lại tương tác
với người dùng cũng như là tương tác lẫn nhau.
* Hàng đợi thông điệp :
Để lưu trữ, phân loại, tương tác… Hệ điều hành Windows xây dựng hàng
đợi thông điệp. Hai loại hàng đợi thông điệp dùng cho mục đích này là:
o Hàng đợi hệ thống (System queue).
o Hàng đợi ứng dụng (Application queue).
Windows có các trình điều khiển thiết bị (Drivers) chịu trách nhiệm cho các
dịch vụ ngắt từ thiết bị phần cứng mouse và keyboard. Tại mỗi thời điểm ngắt phát
sinh, các Driver này gọi một điểm vào (hàm) đặc biệt trong USER.EXE để chỉ ra
rằng một sự kiện vừa xảy ra. Các sự kiện mouse, bàn phím khi xảy ra đều trước hết
được lưu vào hàng đợi hệ thống. Mọi tiến trình trong hệ thống đều chia sẻ hàng đợi.
Hàng đợi hệ thống chỉ làm một nhiệm vụ duy nhất là ghi nhận các sự kiện mouse,
bàn phím (nhấn, rê mouse, nhấn bàn phím…) khi có.
81
Hình 3-1 Hàng đợi ứng dụng
Khi một tiến trình được khởi tạo, một hàng đợi đại diện cho nó được tạo ra,
hàng đợi này (đôi khi được gọi là hàng đợi tác vụ) được dùng để chứa những thông
điệp sẽ được gởi cho các cửa sổ của ứng dụng. Những thông điệp này là những
thông điệp được gởi một cách tường minh bằng một trong hai hàm sau :
o PostMessage
o PostAppMessage
Ứng dụng có thể dùng hai hàm là GetMessage và PeekMessage do
Windows cung cấp để khảo sát hàng đợi của mình. Hai hàm này cho phép ứng dụng
lấy một thông điệp ra khỏi hàng đợi để từ đó phân loại và có những hồi đáp thích
hợp với người dùng.
3.1.2 Hook là gì ?
Hook là một cơ chế xử lý thông điệp của hệ thống mà một ứng dụng có thể
cài đặt một đoạn lệnh (subroutine) để theo lưu thông thông điệp trên hệ thống và xử
lý một số dạng thông điệp nào đó trước khi các thông điệp đến được thủ tục ở cửa
sổ đích.
3.1.3 Đặc tính của hook:
Hook có xu hướng làm chậm hệ thống vì chúng gia tăng số lượng công việc
xử lý của hệ thống cho mỗi thông điệp. Chỉ nên cài đặt hook khi cần thiết, và tháo
bỏ ngay khi không dùng nữa.
82
3.1.4 Các khái niệm trong hook:
3.1.4.1 Hook chains:
Hệ thống hỗ trợ nhiều loại hook; mỗi dạng cung cấp khả năng truy cập đến
khía cạnh khác nhau của cơ chế xử lý thông điệp. Chẳng hạn, ứng dụng có thể dùng
WM_MOUSE hook để kiểm soát lưu thông thông điệp của các thông điệp về
mouse.
Hệ thống duy trì một hook chain (dãy các hook) riêng rẽ cho mỗi loại hook.
Một hook chain là một danh sách các con trỏ trỏ đến các hàm do ứng dụng định
nghĩa, đặc biệt riêng gọi là các hook procedure (thủ tục hook). Khi một thông điệp
phát sinh mà liên quan đến một loại hook, hệ thống chuyền thông điệp cho mỗi
hook procedure tham chiếu từ hook chain, hết cái này đến cái khác. Hoạt động một
hook procedure thực hiện tùy thuộc vào loại hook quy định. Các hook procedure
cho một số loại hook chỉ có thể quan sát các thông điệp; số còn lại có thể chỉnh sửa
thông điệp hay chặn quá trình chuyền thông điệp trong hook chain, ngăn thông điệp
đến được hook procedure kế tiếp hoặc cửa sổ đích.
3.1.4.2 Hook procedure
Để tận dụng khả năng của mỗi loại hook, hệ thống cung cấp một hook
procedure và sử dụng hàm SetWindowsHookEx để cài đặt hook procedure vào
trong hook chain liên quan. Hook procedure phải theo công thức:
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
LPARAM lParam
);
Có thể đặt tên tùy ý, không cần phải đúng là HookProc cho hook procedure.
Tham số nCode là mã hook mà hook procedure dùng để quyết định thao tác
thực hiện. Giá trị mã hook tùy thuộc vào loại hook; mỗi loại lại có bộ mã hook
mang tính chất riêng của nó. Các giá trị của tham số wParam và lParam tùy thuộc
83
mã hook, nhưng chúng đặc biệt chứa thông tin về thông điệp được gởi hay chuyển
(post).
Hàm SetWindowsHookEx luôn cài đặt một hook procedure ở đầu hook
chain. Khi một sự kiện xảy ra mà được quan sát bởi một loại hook, hệ thống sẽ gọi
thủ tục ở đầu hook chain liên quan đến hook. Mỗi hook procedure trong chain quyết
định có nên chuyển sự kiện sang thủ tục kế tiếp. Một hook procedure chuyển sự
kiện sang thủ tục kế bằng cách gọi CallNextHookEx.
Chú ý các hook procedure cho một số loại hook chỉ có thể quan sát thông
điệp mà thôi. Hệ thống chuyển thông điệp cho mỗi hook procedure, mặc cho mỗi
thủ tục có gọi CallNextHookEx.
Một hook toàn cục (global hook) kiểm soát các thông điệp cho mọi tiểu trình
trên cùng desktop với tiểu trình gọi hook. Một hook riêng cho tiểu trình (thread-
specific hook) kiểm sóat các thông điệp cho chỉ riêng tiểu trình đó thôi. Một hook
procedure toàn cục có thể được gọi trong ngữ cảnh của bất kỳ ứng dụng trên cùng
desktop với tiểu trình gọi, vì vậy thủ tục được gọi phải ở trong một module thư mục
liên kết động (dynamic linked library DLL) riêng rẽ. Một hook procedure riêng cho
tiểu trình chỉ được gọi trong ngữ cảnh của tiểu trình liên quan thôi. Nếu ứng dụng
cài đặt hook procedure một trong những tiểu trình của nó, hook procedure có thể
trong cùng module với phần mã còn lại của ứng dụng hay trong một DLL. Nếu một
ứng dụng cài đặt hook procedure cho một tiểu trình của một ứng dụng khác, thủ tục
phải ở trong DLL.
3.1.4.3 Các loại hook
Mỗi loại hook cho phép ứng dụng quan sát các khía cạnh khác nhau của cơ
• WH_CALLWNDPROC và WH_CALLWNDPROCRET Hooks
• WH_CBT Hook
• WH_DEBUG Hook
• WH_FOREGROUNDIDLE Hook
chế xử lý thông điệp của hệ thống. Các loại hook khả dụng là :
84
• WH_GETMESSAGE Hook
• WH_JOURNALPLAYBACK Hook
• WH_JOURNALRECORD Hook
• WH_KEYBOARD_LL Hook
• WH_KEYBOARD Hook
• WH_MOUSE_LL Hook
• WH_MOUSE Hook
• WH_MSGFILTER và WH_SYSMSGFILTER Hooks
• WH_SHELL Hook
Trong các hook kể trên, ta chỉ cần chú ý ba hook dành cho xử lý sự kiện bàn
phím WH_GETMESSAGE, WH_KEYBOARD, WH_KEYBOARD_LL.
3.1.4.3.1 WH_GETMESSAGE Hook
Hook cho phép quan sát các thông điệp sẽ trả về bởi các hàm GetMessage và
PeekMessage, có thể dùng hook để quan sát các dữ liệu nhập từ mouse và bàn phím
và các loại thông điệp khác từ hàng đợi thông điệp.
3.1.4.3.2 WH_KEYBOARD_LL Hook
Cho phép kiểm soát các sự kiện nhập từ bàn phím sẽ được chuyển đi trong
hàng đợi thông điệp.
3.1.4.3.3 WH_KEYBOARD Hook
Cho phép kiểm soát dòng lưu thông các thông điệp WM_KEYDOWN,
WM_KEYUP sẽ trả bởi hàm GetMessage hay PeekMessage. Hook cũng có thể
được dùng để kiểm soát các sự kiện nhập từ bàn phím sẽ được chuyển đi trong hàng
đợi thông điệp.
3.1.5 Tiếp cận vấn đề:
Như vậy, ta phải tạo một hook có khả năng chặn bắt các sự kiện bàn phím,
ghi nhận, cho phép hoặc hủy bỏ trước khi các thông điệp bàn phím đến được cửa sổ
85
đích. Trong các loại hook nêu trên, ta thấy các loại hook phù hợp là:
WH_GETMESSAGE, WH_KEYBOARD, WH_KEYBOARD_LL. Tuy nhiên, mục
tiêu đề ra là làm thế nào để kiểm soát bàn phím mà thôi, WH_GETMESSAGE kiểm
soát hết các thông điệp, đồng thời hạn chế lớn nhất là WH_GETMESSAGE không
có tính năng lọc bỏ thông điệp. Như vậy, ta chọn được hai hook WH_KEYBOARD,
WH_KEYBOARD_LL. Ta chọn WH_KEYBOARD vì dễ cài đặt hơn, tương thích với
nhiều phiên bản hệ điều hành Windows. Do chức năng khóa bàn phím là chức năng
có nhiều kỹ thuật khá thú vị, nên quá trình cài đặt chức năng này sẽ được đề cập
trước.
3.1.5.1 Tinh chế 0:
Xây d(cid:127)ng m(cid:127)t (cid:127)ng d(cid:127)ng (cid:127)(cid:127)n gi(cid:127)n cài (cid:127)(cid:127)t m(cid:127)t hook toàn c(cid:127)c. Khi (cid:127)ng d(cid:127)ng ch(cid:127)y, phím ‘e’ trên bàn phím s(cid:127) b(cid:127) vô hi(cid:127)u hóa (không gõ (cid:127)(cid:127)(cid:127)c n(cid:127)a).
Cài đặt hook toàn cục, ta cần viết các hàm cài đặt, gở bỏ hook và hook
procedure trong một module riêng, gọi là DLL (thư viện liên kết động). Trước hết,
ta cần khảo sát các hàm cài đặt, gở bỏ hook do Windows cung cấp. Các hàM API
này được nêu rõ trong Phụ lục Các hàm API hữu ích sử dụng trong chương
trình gồm: SetWindowsHookEx (cài đặt hook), UnhookWindowsHookEx (gở bỏ
hook), CallNextHookEx (truyền cho hook kế). Các hàm API của Windows từ đây
trở đi khi được đề cập đến nếu được sử dụng nhiều trong chương trình, sẽ được nêu
rõ trong Phụ lục Các hàm API hữu ích sử dụng trong chương trình.
Xây dựng hook procedure:
Đây là lúc thích hợp để đề cập việc xây dựng hàm quan trọng nhất, hook
procedure. Hook procedure là một callback function, tức là một hàm chỉ được gọi
bởi Windows mỗi khi có sự kiện ứng với hàm xảy ra
Các hook procedure đều có dạng sau:
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
86
LPARAM lParam
);
Ta cần sử dụng WH_KEYBOARD nên ta sẽ khảo sát cụ thể hook
procedure cho WH_KEYBOARD:
LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
);
code : xác định cách thức hook procedure xử lý thông điệp, nó là một trong
hai giá trị sau :
HC_ACTION : Thông điệp đã được lấy ra khỏi hàng đợi thông điệp.
wParam và lParam chứa thông tin về thông điệp mà hook procedure nhận được.
HC_NOREMOVE : wParam và lParam mang thông tin của thông điệp, và
thông điệp vẫn còn trong hàng đợi (ứng dụng gọi PeekMessage với tùy chọn
PM_NOREMOVE).
Nếu code âm, hook procedure phải chuyển thông điệp đi bằng cách gọi hàm
CallNextHookEx và trả về kết quả nhận được.
wParam : chứa mã phím ảo của phím được nhấn.
lParam : cho biết số lần lặp lại, mã quét, cờ mở rộng, mã ngữ cảnh, cờ trạng
thái trước của phím, và cờ chuyển trạng thái:
0-15 cho biết số lần lặp phím, là số lần nhấn phím được tính khi người
dùng giữ phím.
16-23 cho biết mã quét.
25-28 dành riêng.
29 cho biết mã ngữ cảnh. Giá trị 1 nếu phím ALT được nhấn, 0 nếu ALT
nhả
30 cho biết trạng thái phím trước đó. Giá trị 1 nếu phím được nhấn trước
khi thông điệp được gởi, 0 nếu ngược lại.
87
31 cho biết trạng thái chuyển đổi. 0 nếu phím đang nhấn, 1 nếu phím
được thả.
Tới đây, ta đã vượt qua một lượng lớn kiến thức khá thú vị về cơ chế hook.
Đã đến lúc làm một việc gì đó cụ thể, ta cài đặt bài tóan nêu ở Tinh chế 0:
Xây dựng các hàm cài đặt gở bỏ: quy tắc viết hàm theo module DLL, cách
nạp một DLL vào bộ nhớ và thực thi, xem chi trong phần mã nguồn chương trình. Ở
đây, ta chỉ đề cập đến cách hàm hoạt động mà thôi.
Hàm cài đặt:
LRESULT __declspec(dllexport) InstallKeyHook()
Cài đặt một WH_KEYBOARD để xử lý thông điệp bàn phím và trả về
handle hook cài đặt thành công hoặc lỗi nếu thất bại.
Hàm gở bỏ:
LRESULT __declspec(dllexport) UninstallKeyHook()
Gở bỏ WH_KEYBOARD hook đã cài đặt, trả về mã thông báo kết quả.
Hook procedure :
LRESULT CALLBACK KeyboardProc(INT nCode, WPARAM wParam,
LPARAM lParam)
Ta chỉ xử lý khi thông điệp được lấy ra khỏi hàng đợi và chỉ xử lý một thông
điệp WM_KEYDOWN mà thôi (khi lọc bỏ thông điệp WM_KEYDOWN thì thông
điệp WM_KEYUP sẽ không được phát sinh, xem chi tiết về thông điệp bàn phím
trong Phụ lục Sự kiện bàn phím). Hai thông điệp WM_SYSKEYDOWN và
WM_SYSKEYUP cũng tương tự như thế.
Thử nghiệm:
Chương trình chạy hoạt động tốt nhưng khi ta thay đổi nhỏ như sau: cố
truyền một biến cho DLL, biến này cho biết mã phím ảo của phím sẽ bị chặn, chẳng
hạn, ‘e’, và truyền cho DLL như sau:
SetX(‘e’); //SetX là hàm đặt biến trong DLL.
và trong DLL khai báo một biến toàn cục như sau:
WPARAM x;
88
thì chương trình sẽ mất tác dụng khi ứng dụng của ta mất focus (không phải
là cửa sổ đang kích họat). Điều này không chấp nhận được vì ứng dụng ta mong
muốn cần phải chặn bắt các sự kiện bàn phím khi người dùng đang sử dụng.
Hình 3-2 Tinh chế 0
3.1.5.2 Tinh chế 1:
Xây d(cid:127)ng m(cid:127)t (cid:127)ng d(cid:127)ng cài (cid:127)(cid:127)t m(cid:127)t hook toàn c(cid:127)c. Khi (cid:127)ng d(cid:127)ng ch(cid:127)y, tùy theo phím ng(cid:127)(cid:127)i dùng gõ vào mà (cid:127)ng d(cid:127)ng s(cid:127) khóa phím (cid:127)ó.
Để giải quyết vấn đề, ta cần phải tìm hiểu kỹ cơ chế hoạt động cũng như tải
nạp một module DLL vào bộ nhớ khi ứng dụng cần. Điều cốt lõi ta cần biết chính là
không gian địa chỉ. Khi một DLL toàn cục được thực thi, nó sẽ thực thi trong ngữ
cảnh của tiến trình mà có sự kiện nó cần hook đang xảy ra. Vì đây là một DLL, nó
sẽ có một bản sao riêng rẽ của những dữ liệu cần dùng của nó (trong trường hợp ta
khảo sát, đó là biến toàn cục x) cho mỗi tiến trình. Vì vậy, mỗi lần hook procedure
được gọi, DLL sẽ nạp vào không gian địa chỉ của tiến trình cần hook, và một loạt
các dữ liệu mà DLL dùng sẽ được khởi tạo mới (chẳng hạn các biến toàn cục khai
báo ở mức độ tập tin như biến x đã nêu trên). Vì vậy, ta phải làm một cách nào đó
mà các dữ liệu ta cần (biến x) có thể dùng cho mọi thể hiện của DLL. Điều này có
thể thực hiện được bằng cách sử dụng đọan không gian địa chỉ chia sẻ (shared
segment), xem thêm chi tiết về vấn đề này trong phần Phụ lục DLL – thư viện liên
kết động.
89
Khi đó, do các biến ta cần đều được đặt trong đoạn không gian địa chỉ chia
sẻ, các thể hiện của DLL được nạp trong mỗi tiến trình đều “hiểu” (đọc được giá trị
trong bản gốc DLL nạp do ứng dụng của ta đặt). Để khai báo một phân đoạn không
gian địa chỉ chia sẻ, ta làm như sau:
#pragma data_seg(“.VAN”)
//Các biến cần sử dụng chung
#pragma data_seg()
#pragma comment(linker, “/section:.VAN,rws”)
với “.VAN” là tên đặt gợi nhớ tùy ý cho phân đoạn (nhưng không được dài
hơn 8 ký tự). #pragma comment ở trên đặt thêm một tùy chọn biên dịch cho các tập
tin biên dịch .OBJ.
Đến đây, mọi việc lại trở nên quá dễ dàng với phân đọan chia sẻ ta vừa tạo
ra. Ta chỉ việc tạo ra 255 biến trạng thái (kể cả các ký tự điều khiển và mở rộng, có
thể có tới 256 ký tự). Các biến này lưu trữ trạng thái của phím như sau:
#define MAX_KEYS_LOCK 255
static BOOL g_bHook[MAX_KEYS_LOCK]
với FALSE cho biết phím chưa khóa
TRUE cho biết phím đã khóa
đặt mảng các biến vào trong phân đọan vừa tạo trên và chỉnh sửa lại hook
procedure KeyboardProc:
Thế là ta hoàn tất vấn đề chính. Việc còn lại chỉ đơn giản là thiết lập hàm ghi
giá trị biến trong DLL và gọi nó trong ứng dụng
Thử nghiệm tinh chế 1:
Chương trình hoạt động khá tốt nhưng ta vẫn chưa đề cập đến các phím chức
năng (ví tổ hợp Alt-Tab…). Thật vậy, chương trình hoàn toàn bất lực trước các
phím chức năng vì ta không thiết kế chức năng “nhập” các phím chức năng, mà cho
dù có, ta cũng không “bắt” được. Điều này không chấp nhận được vì ứng dụng ta
mong muốn cần phải chặn bắt các sự kiện bàn phím khi người dùng đang sử dụng.
90
Hình 3-3 Tinh chế 1
3.1.5.3 Tinh chế 2:
Xây d(cid:127)ng m(cid:127)t (cid:127)ng d(cid:127)ng cài (cid:127)(cid:127)t m(cid:127)t hook toàn c(cid:127)c. Khi (cid:127)ng d(cid:127)ng ch(cid:127)y, cho phép vô hi(cid:127)u hóa b(cid:127)t k(cid:127) phím nào trên bàn phím.
Để giải quyết vấn đề này, ta cần xem xét lại khả năng của hook
WH_KEYBOARD. Hook không có khả năng chặn bắt các tổ hợp phím như: Alt-
Tab… Vì vậy, ta đành phải sử dụng hook khả dĩ cuối cùng là hook
WH_KEYBOARD_LL. Tuy nhiên, hook là một hook mới có từ Windows
NT/2000/XP trở về sau. Đây là một hook rất mạnh nhưng cách dùng cũng như
tham số đầu vào khác rất nhiều so với WH_KEYBOARD. Do đó, ta phải tinh chỉnh
lại hook procedure nếu không muốn thay đổi toàn bộ cài đặt từ trước.
Khảo sát hook procedure của WH_KEYBOARD_LL :
LRESULT CALLBACK LowLevelKeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam
);
Ý nghĩa tham số:
91
[in]
nCode: xác định cách thức xử lý thông điệp. Nếu nCode âm, phải chuyển
thông điệp sang hook procedure kế, và trả về kết quả nhận được, chỉ có thể là giá
trị:
HC_ACTION wParam và lParam chứa thông tin về thông điệp bàn phím.
wParam: xác định loại thông điệp. Đó là: WM_KEYDOWN, WM_KEYUP,
WM_SYSKEYDOWN, và WM_SYSKEYUP.
lParam: trỏ đến cấu trúc KBDLLHOOKSTRUCT.
Cấu trúc KBDLLHOOKSTRUCT như sau:
typedef struct {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
Có ý nghĩa như trong Phụ lục Sự kiện bàn phím.
Ý nghĩa tham số:
[in]
vkCode : mã phím ảo từ 1-254.
scanCode: mã quét phần cứng.
flags: cờ phím mở rộng, cờ sự kiện thêm vào, mã ngữ cảnh, và cờ chuyển
đổi trạng thái. Ứng dụng dùng các giá trị sau để kiểm tra cờ nhấn phím
Value Purpose
LLKHF_EXTENDED Kiểm tra cờ mở rộng.
LLKHF_INJECTED Kiểm tra cờ thêm sự kiện.
LLKHF_ALTDOWN Kiểm tra mã ngữ cảnh.
LLKHF_UP Kiểm tra cờ chuyển trạng thái.
92
Bảng 3-1 Giá trị khảo sát phím mở rộng
cho biết phím có là phím mở rộng hay không, chẳng hạn như phím 0
chức năng hay phím bên bảng số (numpad). Giá trị 1 nếu đúng, 0 nếu
sai.
1-3 Dành riêng.
Cho biết sự kiện này có phải do được thêm vào không (chứ không 4
phải do từ bàn phím gõ). Giá trị 1 nếu đúng, 0 nếu sai.
Cho biết mã ngữ cảnh, phím alt có được nhấn hay không. Giá trị 1 5
đúng, nếu
0 nếu sai.
6 Dành riêng.
7 Cho biết trạng thái phím. Giá trị 0 nếu phím nhấn và một nếu phím
được thả.
time Cho biết tem thời gian của thông điệp.
dwExtraInfo Cho biết các thông tin đi kèm thêm với thông điệp.
So sánh với các tham số của WH_KEYBOARD, ta cần giả lập wParam,
lParam của WH_KEYBOARD từ wParam, lParam của WH_KEYBOARD_LL.
wParam: khá dễ dàng, wParam của WH_KEYBOARD chính là vkCode
trong cấu trúc KBDLLHOOKSTRUCT do lParam của WH_KEYBOARD_LL trỏ
đến.
lParam: phức tạp hơn một chút, ở đây ta phải giả lập lại giá trị DWORD của
lParam trong WH_KEYBOARD từ cấu trúc KBDLLHOOKSTRUCT do lParam
của WH_KEYBOARD_LL trỏ đến. Hàm MakeFakelParam sẽ giúp ta làm điều này:
LPARAM MakeFakelParam(PKBDLLHOOKSTRUCT pKb)
Hàm có tác dụng chuyển đổi giá trị lParam trong cấu trúc
KBDLLHOOKSTRUCT sang giá trị lParam của WH_KEYBOARD.
Tuy thế, mọi việc vẫn chưa kết thúc. Rắc rối xảy ra khi ta nhấn phím ALT.
Phím ALT sẽ nhận biết được nếu ta nhấn phím mà không kèm theo một phím khác.
93
Phím sẽ không biết được nếu ta nhấn kèm với phím khác vì khi đó, driver bàn phím
sẽ thông dịch phím ALT thành mã ngữ cảnh. Vì vậy, đối với riêng tình huống này ta
phải xử lý riêng:
So sánh thêm mã ngữ cảnh:
if( (g_bHook[VK_LMENU]) || (g_bHook[VK_RMENU]) )
if(p->flags & LLKHF_ALTDOWN) // co nhan kem alt voi phim nay
return 1;
Như vậy bài tóan tinh chế 2 đã được giải quyết hoàn chỉnh.
chèn hình
Thử nghiệm:
Chương trình chạy tốt yêu cầu đề ra. Lưu ý rằng do tính chất là một hook cấp
thấp, nên vấn đề nhận biết số lần lặp lại phím khá phức tap. Ta có thể bỏ qua việc
này vì ứng dụng thực sự của ta không cần đến.Vấn đề còn lại là ghi nhận phím, một
keylogger đơn giản, ít phức tạp hơn nhiều.
Hình 3-4 Tinh chế 2
3.1.5.4 Tinh chế 3:
Xây d(cid:127)ng m(cid:127)t (cid:127)ng d(cid:127)ng cài (cid:127)(cid:127)t m(cid:127)t hook toàn c(cid:127)c. Khi (cid:127)ng d(cid:127)ng ch(cid:127)y, xu(cid:127)t ra màn hình ký t(cid:127) ng(cid:127)(cid:127)i dùng gõ.
Ta cần lưu ý kỹ thuật lập trình truyền thông điệp chứa dữ liệu ký tự phím gõ
từ hook procedure đến cửa sổ xử lý. Điều này có thể thực hiện được khi lúc ban đầu
94
khởi tạo hook ta cần cho hook biết cần kiểm sóat bao nhiêu phím (cả bàn phím),
handle cửa sổ chính, loại thông điệp (ứng dụng ta không cần quan tâm nên ta chỉ
cần thông điệp WM_KEYDOWN), các loại cửa sổ cần kiểm sóat (mọi cửa sổ), các
phím kết hợp kèm theo (ta không quan tâm). Tất cả các thông tin trên được gọi là
một bộ kiểm sóat (entry). Hàm LogKeyboard sẽ giúp ta làm điều này:
LRESULT CKeyLogClient::LogKeyboard(HWND hWnd)
Hàm sẽ gọi hàm AddKeyEntry, là một hàm trong DLL. Hàm có tác dụng lưu
trữ các dữ liệu trên. Khi đó, cài đặt hook xong ta chỉ việc đợi kết quả gởi tới cửa sổ
xử lý. Dĩ nhiên, hook procedure cần sửa lại để thông báo cho cửa sổ cài đặt hook
biết có thông điệp mã phím cần xử lý (sử dụng hàm PostMessage gởi thông điệp tự
định nghĩa cho cửa sổ chính với handle cửa sổ chính nhận được từ hàm
LogKeyboard).
LRESULT CALLBACK KeyboardProc(INT nCode, WPARAM wParam,
LPARAM lParam)
Thử nghiệm:
Như vậy, ta đã hoàn tất được mục tiêu đề ra ban đầu. Mặc dù chương trình
hoàn chỉnh phải bao gồm nhiều kỹ thuật lập trình thú vị khác, nó lại không nằm
trong phạm vi tìm hiểu mà mục tiêu ta cần. Chương trình hoàn chỉnh còn có thêm
khả năng sử dụng hook cho đồng thời tối đa 256 tiến trình và tối đa 1024 bộ kiểm
sóat. Phần việc còn lại chỉ cần thay đổi một ít mã nguồn để tích hợp vài chương
trình chính.
95
Hình 3-5 Tinh chế 3
3.2 Xây dựng màn hình che:
Trong quá trình thực hiện phần mềm, có một yêu cầu cần thiết cho chương
trình quản lý phòng máy là cần phải ngăn chặn người dùng không dùng máy khi
chưa đăng ký với người quản trị để sử dụng. Một điều thực tế hiển nhiên là các máy
tính trong phòng máy phải luôn bật máy sẵn sàng. Vì vậy, ta cần xây dựng một màn
hình che trên màn hình để người dùng không thể tương tác với máy.
3.2.1 Phân tích sơ lược:
Ta nhận thấy rằng để tương tác với máy tính, thông thường người dùng sẽ sử
dụng hai thiết bị tương tác là mouse và bàn phím. Ta không cần quan tâm về các
loại thiết bị tương tác khác vì thông thường các phòng máy chỉ cần hai thiết bị nêu
96
trên là đủ. Vì vậy, ta sẽ xem xét các tương tác của người dùng để sử dụng máy tính
bằng hai thiết bị trên.
Sau khi khảo sát, quy trình sử dụng máy thông thường sẽ là:
1. Bật máy lên
2. Nếu có icon chương trình cần chạy trên desktop, kích hoạt chương trình.
3. Nếu chương trình không có trên desktop, người dùng sẽ lục tìm trên máy
bằng nhiều cách khác nhau như :
a. Nhấn Start, dò trên All Programs.
b. Nhấn Start, chạy Run, mở gõ chương trình cần chạy.
c. Chạy My Computer, dò chương trình trong cây thư mục.
d. Mở Windows Explorer, dò chương trình trong cây thư mục.
e. …
4. Khi sử dụng xong chương trình, người dùng đóng chương trình lại.
5. Quay trở lại bước 2 Vòng lặp sẽ xảy ra cho đến khi người dùng sử dụng
xong máy tính.
6. Tắt máy tính.
Các bước 1 và 6 có thể được bỏ qua. Ta sẽ xem xét các bước từ 2 đến 6. Dễ
dàng nhận thấy rằng mọi tương tác của người dùng thông thường đều phải
thông qua desktop. Nếu ta làm cách nào đó ngăn chặn việc tương tác của
người dùng trên desktop, ta sẽ đạt được mục tiêu đề ra. Từ đây, ta sẽ đưa ra các
khảo sát cụ thể cho mỗi thiết bị mouse và bàn phím.
3.2.1.1 Tương tác bằng mouse:
Đây là thiết bị chủ yếu người dùng sẽ sử dụng để tương tác với máy tính.
Phần lớn người dùng thông thường sẽ không biết sử dụng máy, hoặc sẽ rất khó khăn
khi sử dụng máy mà không có mouse. Do tính phổ thông và cần thiết như thế, người
dùng sẽ phụ thuộc rất nhiều vào mouse.
Vẫn theo ý tưởng đề ra ở trên, ta để ý rằng thực chất desktop chỉ là một cửa
sổ của Windows, trên đó, mọi ứng dụng sẽ được chạy (mọi cửa sổ ứng dụng được
97
mở trên desktop đều là cửa sổ con của nó). Nếu có một cửa sổ nào đó nằm chồng
lên trên desktop, và cửa sổ đó đang kích hoạt, thì người dùng sẽ tương tác với cửa
sổ đó chứ không thể tương tác với desktop. Để có thể tương tác trở lại với desktop,
người dùng phải click mouse trái lên trên desktop (trong trường hợp cửa sổ bình
thường), nhấn nút Minimise trên thanh tiêu đề của cửa sổ (trong trường hợp cửa sổ
bình thường hoặc đang phóng to hết cỡ). Điều gì sẽ xảy ra nếu người dùng không
còn những khả năng trên :
o không thể click chuột trái lên trên desktop vì cửa sổ đang được phóng to hết
cỡ (maximized), che mất cả desktop và cả thanh taskbar .
o không thể thu nhỏ cửa sổ lên trên thanh taskbar, phục hồi cửa sổ lại kích
thước thông thường, và tắt cửa sổ đi vì cửa sổ không có thanh tiêu đề.
Đến đây, ta đã thấy rõ cách làm. Điều duy nhất cần làm bây giờ là :
o tạo một cửa sổ không có thanh tiêu đề.
o kích hoạt cửa sổ mỗi khi máy vừa khởi động xong.
o “căng” kích cở của cửa sổ sao cho vừa khít với desktop.
Để làm được điều này, ta sẽ sử dụng các kỹ thuật và hàm thông thường được
cung cấp sẵn bởi Windows mà ta sẽ đề cập kỹ ở phần cài đặt. Bây giờ, đã đến lúc đề
cập đến bàn phím.
3.2.1.2 Tương tác với bàn phím:
Đây là thiết bị quan trọng thứ hai sau mouse để người dùng tương tác với
desktop. Phần lớn người dùng thông thường chỉ sử dụng bàn phím nhiều khi họ sử
dụng máy tính là đánh văn bản. Trong phòng máy tính Café Internet, bàn phím
được dùng để chat, nhập thông tin người dùng trong lúc lướt web… Chỉ có một số
nhỏ người dùng am hiểu rõ và ghi nhớ các phím tắt do Windows gán để tương tác
với desktop. Chẳng hạn, xem bảng so sánh các thao tác bằng mouse và bàn phím
qua hai thao tác hay dùng là mở Control Panel và shutdown máy:
Bằng mouse Bằng bàn phím
98
1. Mở Control Panel 1. Mở Control Panel
a. Nhấn Win key, hoặc Ctrl-Esc a. Nhấn Start
b. Nhấn phím r, kích hoạt cửa sổ Run
c. Gõ “control” trong ô Open (không có dấu “”) b. Chọn All Programs
d. Nhấn Enter c. Chọn Control Panel
2. Shutdown máy: 2. Shutdown máy :
a. Nhấn Win key, hoặc Ctrl-Esc. a. Nhấn Start
b. Nhấn phím r, kích hoạt cửa sổ Run. b. Chọn Turn off
c. Gõ “shutdown /s /t 0” trong ô Open (không có Computer
dấu “”) c. Chọn tiếp Turn off
d. Nhấn Enter
Bảng 3-2 So sánh tương tác giữa mouse và bàn phím
Tùy thuộc vào cấu hình các phiên bản Windows mà các bước thực hiện có thể khác
đôi chút, ở đây ta sử dụng WindowsXP chế độ taskbar là “Start menu”, chế độ log
off là “Using Welcome Screen”.)
Nhìn chung các thao tác bằng bàn phím khá phức tạp hơn bằng mouse, tựu
trung lại chỉ cần nhớ phím và tổ hợp phím thực thi, câu lệnh, và làm một việc duy
nhất là …gõ. Do vậy, ta chỉ cần làm một việc duy nhất là vô hiệu hóa toàn bộ phím
bấm trên bàn phím là xong mà ta sẽ đề cập kỹ ở phần cài đặt.
3.2.2 Cài đặt:
Ta sẽ thực hiện những bước đề ra như ở trong phần 1.2.1 Phân tích sơ lược
lần lượt cho mỗi thiết bị.
3.2.2.1 Tương tác với mouse:
Ta sẽ tạo một cửa sổ. Tuy nhiên, cửa sổ theo dạng tài liệu (document) như
WinWord, Windows Explorer… không phù hợp cho mục tiêu. Cái ta cần sẽ là một
cửa sổ dạng hộp thoại (dialog), vì ta về sau có thể cần chèn hình ảnh giới thiệu. Vả
lại, ta cần một cửa sổ càng đơn giản càng tốt (ít cấu hình sẵn), hỗ trợ thiết kế trực
99
quan… thì trong Microsoft Visual Studio 6.0 viết chương trình bằng MFC, loại
project theo Dialog-based là thích hợp nhất.
Sau khi tạo một hộp thoại xong, ta cần cho cửa sổ “nổi” lên trên tất cả cửa sổ
khác kể cả desktop và thanh taskbar và “căng” kích cỡ chiếm hết cả màn hình. Hàm
API SetWindowPos sẽ giúp ta điều này.
Tuy thế, ta sẽ không gọi trực tiếp hàm API SetWindowPos mà gọi thông qua
phương thức của CWnd, lớp cha của lớp cửa sổ thoại, SetWindowPos:
Phương thức chỉ khác hàm API ở chỗ chỉ có 6 tham số ứng lần lượt với 6
tham số cuối của hàm API. Phương thức sẽ thực thi bằng cách gọi lại hàm API và
thêm tham số đầu tiên của hàm API băng handle cửa sổ có sẵn cửa sổ lớp hộp thoại
m_hWnd.
Đến đây, có một vấn đề nhỏ cần giải quyết là lấy được kích thước của
desktop, hay nói cách khác là độ phân giải của màn hình. Ta không thể lấy cố định
kích thước, ví dụ là 800x600, vì mỗi màn hình sẽ được người dùng sẽ thay đổi độ
phân giải cho phù hợp với mắt nhìn. Do vậy, có hai cách giải quyết :
a. Đọc trực tiếp các giá trị độ dài và độ rộng của màn hình bằng hàm API
GetSystemMetrics:
Áp dụng hàm trong chương trình như sau:
int xScrn = ::GetSystemMetrics(SM_CXSCREEN);
int yScrn = ::GetSystemMetrics(SM_CYSCREEN);
SetWindowPos(&wndTopMost, 0, 0, xScrn, yScrn,
SWP_SHOWWINDOW);
Đọan mã trên đặt trong phương thức khởi tạo của cửa sổ hộp thoại, tham số
&wndTopMost nhằm đặt cửa sổ vào dãy thứ tự các cửa sổ dạng “nổi trội”, các tham
số sau có ý nghĩa là dời cửa sổ về góc trên bên phải màn hình, độ rộng và dài bằng
độ phân giải màn hình, kích hoạt và hiện cửa sổ.
b. Đọc các giá trị độ rộng và dài từ hai hàm API CreateDC,
GetDeviceCaps. Dùng cách này có tiện lợi khi hệ thống có nhiều màn hình hiển
thị:
100
hàm API CreateDC: tạo ngữ cảnh thiết bị
hàm API GetDeviceCaps: lấy các thông số của thiết bị.
Áp dụng mã vào chương trình như sau:
HDC hScrDC;
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
int xScrn, yScrn;
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//resize cho lon nhat . Day la topmost window
SetWindowPos(&wndTopMost, 0, 0, xScrn, yScrn,
SWP_SHOWWINDOW);
Hai dòng đầu tạo một HDC cho thiết bị màn hình hiển thị, do tính chất đặc
biệt của màn hình mà hàm chỉ cần nhận tham số tên “DISPLAY” là có thể trả về kết
quả.
Ba dòng kế tiếp có tác dụng lấy độ rộng và độ dài của màn hình. Dòng cuối
là gọi phương thức SetWindowPos như cách 1.
Có một lưu ý nhỏ ở đây là ta vẫn có thể sử dụng thay thế hàm
SetWindowPos bằng một hàm API khác là MoveWindow. Để biết chi tiết hàm, xem
thêm trong Phụ lục Các hàm API hữu ích sử dụng trong chương trình. Hàm
API này tuy có chức năng tương tự với SetWindowPos nhưng hàm lại không có
chức năng quản lý việc “nổi” lên trên cửa sổ khác.Mặc dù theo thiết kế ban đầu khi
khởi động xong, chỉ có một cửa sổ màn hình che phủ toàn bộ màn hình, rất có khả
năng người dùng nhanh tay kích hoạt một cửa sổ nào đó trên desktop. Khi ấy, sử
dụng hàm MoveWindow lại không làm cửa sổ “nổi” lên trên tất cả các cửa sổ còn
lại. Hàm SetWindowPos lại có thêm tác dụng hữu ích này.
Thử nghiệm:
Chương trình vô hiệu hóa tuyệt đối việc tương tác của người dùng với
desktop bằng mouse. Chỉ còn lại một việc nữa phải làm là vô hiệu hóa bàn phím.
101
Hình 3-6 Màn che mouse
3.2.2.2 Tương tác bằng bàn phím:
Mục tiêu ban đầu là không cho người dùng gõ những phím tắt kích hoạt
chương trình. Tuy nhiên, ta không cần vô hiệu hóa cả bàn phím. Điều này rất lãng
phí công sức. Thực chất, ta thực hiện mục tiêu dưới điều kiện hoàn thành ngăn chặn
tương tác với mouse. Vì vậy các loại tương tác làm cho xuất hiện các chương trình
thông thường như Windows Explorer (Win key + E)… không làm ta quan tâm vì
các cửa sổ chương trình đó không thể “nổi” bằng cửa sổ màn hình che. Vì vậy, chỉ
còn lại các loại phím và tổ hợp phím tắt “nhạy cảm” cấp thấp mà thôi. Các loại
phím tắt đó là:
o Win key : có tác dụng bật Start menu.
o Alt + Tab : có tác dụng đổi cửa sổ đang hoạt động.
o Alt + Esc : có tác dụng kích hoạt cửa sổ kế trên thanh taskbar.
102
o Ctrl + Esc: có tác dụng tương tự Win key
o Ctrl + Shift + Esc : có tác dụng bật Task Manager.
o Esc : đây là vấn đề về kỹ thuật làm, theo thiết kế ta tạo một cửa sổ hộp thoại
đơn giản, nên chịu tác dụng của phím Esc, có tác dụng tắt cửa sổ màn che.
o Alt + F4 : có tác dụng tắt cửa sổ màn hình che.
o Ctrl + Alt + Del : có tác dụng bật Task Manager, hay hộp lựa chọn tùy theo
cấu hình Windows (đây là tổ hợp phím gây “nhức đầu” nhiều nhất, ta sẽ đề
cập kỹ trong phần sau).
o Ctrl + Shift + Esc : bật Task Manager.
May mắn thay, trong 7 tổ hợp phím đầu, ta dễ dàng loại bỏ khi sử dụng kỹ
thuật lập trình bằng hook, xem chi tiết về kỹ thuật này trong 3.1 Kỹ thuật lập trình
sự kiện và hook và mã nguồn chương trình. Ta chỉ áp dụng xây dựng một hook
đơn giản lọc bỏ trong quá trình đợi đăng nhập và loại bỏ khi đăng nhập xong. Tuy
nhiên, với 2 tổ hợp phím cuối cùng, Ctrl + Alt + Del và Ctrl + Shift + Esc (về sau ta
gọi tắt chỉ một mình tổ hợp Ctrl + Alt + Del vì tổ hợp Ctrl + Shift + Esc cũng có
tính năng tương tự), khá phức tạp. Ta phải hiểu rõ cơ chế truyền gởi thông điệp Ctrl
– Alt – Del.
Hook bàn phím không thể bắt được tổ hợp phím Ctrl – Alt – Del ! Tại sao ?
Vì chính bản thân hệ điều hành Windows không hề gởi tổ hợp phím này cho hook
chain. Nó đã được chặn bắt và xử lý ở mức thấp hơn ở hệ thống và không bao giờ
được gởi lên ứng dụng. Ứng dụng nếu có cài đặt cũng chỉ nhận được các phím Ctrl,
Alt, và Del rời rạc chứ không phải là tổ hợp Ctrl – Alt – Del.
Tổ hợp phím sau đó sẽ gởi đến cơ chế khởi động đăng nhập của Windows,
gọi là Winlogon, gồm 3 thành phần : thành phần thực thi (“winlogon.exe”), thư viện
liên kết động “Chứng thực và nhận dạng theo cơ chế đồ họa” (Graphical
Identification and Authentication GINA) (“msgina.dll”), và các thành phần mạng.
Tham khảo các tài liệu, ta tìm thấy các cách khống chế tổ hợp Ctrl – Alt –
Del, một số cách dựa trên việc khống chế một trong hai thành phần đầu trong cơ
chế khởi động đăng nhập của Windows như sau:
103
• Giả lập “lừa” hệ điều hành rằng đang có một screensaver đang chạy, tổ hợp
phím được gởi nhưng không kích hoạt Task Manager. Tuy nhiên, cách này
chỉ có tác dụng ở các phiên bản hệ điều hành Win98, không có tác dụng trên
WinXP. Cách này cũng rất hạn chế khi chỉ có tác dụng khi có thiết lập hệ
thống phù hợp, một số tài liệu cho rằng cả phiên bản hệ điều hành Win98
• Vô hiệu hóa Task Manager bằng chính sách (policy). Cách này không hề xử
cũng không có tác dụng !.
lý ở “gốc”, chặn bắt thông điệp Ctrl – Alt – Del, mà xử lý ở “ngọn”, đặt
chính sách hệ thống ngăn chặn kích hoạt Task Manager. Cách này đơn giản
nhưng không dùng được vì thông điệp thông báo :
Hình 3-7 Thông báo của policy về việc vô hiệu hóa Task Manager
• Bắt thông điệp ở tận “gốc” khi xây dựng driver thiết bị bàn phím. Lúc đó,
khá bực mình, lại còn làm xuất hiện Start Menu.
phải sử dụng Device Development Kit (bộ phát triển thiết bị). Đây là lĩnh
vực lập trình hoàn toàn mới, với thời gian nghiên cứu không cho phép, ta bỏ
• Viết một GINA stub. GINA là một thư viện liên kết động mà Winlogon dùng
qua khả năng này.
để chứng thực người dùng. Đây là một cách khá hay, nhưng nó lại làm thay
đổi cách đăng nhập của người dùng đồng thời vô hiệu hóa màn hình
Welcome, và chớp màn hình mỗi khi người dùng nhấn Ctrl – Alt – Del. Tuy
ta không sử dụng cách này nhưng có thể xem thêm về kỹ thuật này trong
• Tạo một desktop mới và chuyển sang desktop mới này. Vì kích hoạt Task
Phụ lục GINA stub – kỹ thuật xây dựng.
Manager bằng tổ hợp phím Ctrl – Alt – Del chỉ làm xuất hiện Task Manager
104
trên “Default” desktop (desktop cũ), nên trên desktop mới sẽ không có xuất
hiện. Cách này khá hiệu quả khi ta xây dựng màn hình che bên desktop mới,
người dùng đăng nhập vào thì trở lại desktop cũ. Khuyết điểm nhỏ của cách
này là hơi phức tạp về mặt lý thuyết cài đặt chương trình, và người dùng
đăng nhập vào thành công sẽ thấy Task Manager hiện ra mặc dù trước đó có
vẻ việc nhấn Ctrl – Alt – Del không có tác dụng. Tuy ta không sử dụng cách
này nhưng có thể xem thêm về kỹ thuật này trong Phụ lục Tạo thêm và sử
• Kế thừa, trở thành lớp con của lớp cửa sổ SAS trong tiến trình Winlogon. Để
dụng Desktop mới.
làm được điều này, mã phải được “chích” (inject) vào tiến trình Winlogon và
sau đó tạo lớp con kế thừa Windows Procedure. Kỹ thuật này không tương
thích với Windows 95/98/Me. Ta sẽ sử dụng kỹ thuật này để vô hiêu hóa
tổ hợp phím Ctrl – Alt - Del.
Module xây dựng gồm có hai phần lớn : tạo lớp con kế thừa lớp cửa
sổ SAS của Winlogon.
* Tạo lớp con kế thừa lớp cửa sổ SAS của Winlogon:
Hàm API SetWindowLong sẽ giúp ta thực hiện điều này:
Áp dụng hàm vào trong chương trình:
SetWindowLong(hWnd, GWL_WNDPROC, NewWindowProc);
Lời gọi chỉ có tác dụng cho các cửa sổ được tạo bởi cùng ứng dụng
gọi hàm (địa chỉ hàm NewWindowProc chỉ có nghĩa với tiến trình gọi hàm
SetWindowLong). Như vậy, ta sẽ dùng một cách nào đó ánh xạ được điạ chỉ của
NewWindowProc vào trong không gian địa chỉ của tiến trình ở xa và chuyển địa
chỉ đó đến lời gọi hàm SetWindowLong. Để có thể hiểu cơ chế nạp một chương
trình vào bộ nhớ, cũng như định nghĩa về không gian địa chỉ của tiến trình, xem
thêm Phụ lục Quá trình nạp một hook DLL toàn cục.
Bây giờ, ta sẽ bàn về kỹ thuật injection.
* Kỹ thuật injection:
105
Khả năng ứng dụng của kỹ thuật injection rất mạnh mẽ và hữu ích.
Ưu điểm này cũng lại là khuyết điểm. Vì càng có nhiều khả năng ứng dụng mà
không bị hạn chế, kỹ thuật injection đòi hỏi các lập trình viên cần phải lập trình cực
kỳ cẩn thận các đọan mã mà họ sẽ “chích” vào tiến trình ở xa. Mọi hành động
“chích” lầm sẽ dẫn đến hậu quả cực kỳ nguy hiểm như crash chương trình ở xa, treo
máy… Tuy nhiên, việc lập trình thành công bằng kỹ thuật injection sẽ gợi mở
nhiều khả năng lập trình thú vị như : xem mật khẩu dạng * trên một cửa sổ khác,
Hình 3-8 Ứng dụng xem mật khẩu từ cửa sổ khác
điều khiển hoạt động của các tiến trình hệ thống Windows như : giấu tên tiến trình
đang chạy trong hai tab Applications” và “Processes” của Task Manager, … đặc
biệt là ứng dụng mà ta cần là vô hiệu hóa Ctrl – Alt – Del.
Vậy thực chất kỹ thuật injection là gì ? Kỹ thuật ánh xạ bộ nhớ (mã chương
trình) vào trong không gian địa chỉ của một tiến trình ở xa được gọi là kỹ thuật
injection.
• Registry. Để “chích” một DLL vào một tiến trình, chỉ cần đơn giản thêm tên
Việc injection có thể thực hiện bởi một trong những cài đặt sau:
DLL đó vào trong khóa registry:
HKLM\Software\Microsoft\Windows NT\
106
CurrentVersion\Windows\AppInit_DLLs:STRING
• Hook. Cách này hỗ trợ trên mọi phiên bản Windows.
• Sử dụng CreateRemoteThread()/LoadLibrary(), chỉ đúng với
chỉ hỗ trợ trên Windows NT trở lên.
• Sao chép mã trực tiếp vào tiến trình ở xa bằng WriteProcessMemory()
Windows NT và cao hơn.
và thực thi nó bằng hàm CreateRemoteThread(), chỉ đúng với
Windows NT và cao hơn.
Mức độ cẩn thận trong lập trình tăng dần từ trên xuống trong 4 cài đặt của kỹ
thuật, tỉ lệ nghịch với việc tiêu tốn tài nguyên (giảm dần từ trên xuống). Cơ chế
hook vẫn áp dụng được trong kỹ thuật này nhưng việc áp dụng nó khá tiêu tốn tài
nguyên hệ thống. Ta sẽ thực hiện phương án cuối để áp dụng kỹ thuật injection cho
cài đặt trong phần mềm. Phương án 3 cũng khả thi nhưng lại không ổn định, tùy
thiết lập của máy mà phương án thành công hay không, có thể xem thêm phương án
này trong mã nguồn chương trình.
Ở đây, ta sẽ mô tả cài đặt cuối :
Chương trình sử dụng cài đặt cuối qua hai hàm InjectCode, và
EjectCode. InjectCode thực hiện việc sao chép dữ liệu và trong tiến trình của
cửa sổ SAS. Các dữ liệu này là : InjectFunc, “khung” thực thi của tiểu trình,
GetSASWnd, tìm handle của cửa sổ SAS, SASWindowProc, hàm window
procedure của lớp con kế thừa, INJDATA, các dữ liệu đầu vào.
Hàm InjectCode
int InjectCode ()
Bỏ qua các chi tiết rườm rà về kỹ thuật (cấp phát bộ nhớ bên tiến trình ở xa,
kỹ thuật lấy vùng nhớ …) thì hàm InjectCode làm những động tác sau:
o Lấy địa chỉ hàm FindWindowA trong DLL USER32.DLL.
o Mở tiến trình winlogon.exe với truy cập toàn quyền.
o Sao chép dữ liệu INJDATA với khởi tạo gồm tên lớp "SAS Window class",
tên cửa sổ "SAS window", địa chỉ hàm FindWindowA vào tiến trình ở xa.
107
o Sao chép hàm GetSASWnd vào trong tiến trình ở xa.
o Tạo tiểu trình thực hiện việc tìm kiếm handle của cửa sổ SAS.
o Nếu thành công, sẽ trả về handle cửa sổ SAS.
o Sao chép nội dung hàm SASWndProc vào trong tiến trình ở xa.
o Sao chép dữ liệu INJDATA với khởi tạo gồm địa chỉ hàm SetWindowLong
(tùy theo tiến trình ở xa có sử dụng Unicode hay không mà sẽ chép tương
ứng hàm dạng SetWindowLongA hay SetWindowLongW),
CallWindowProc (tùy theo tiến trình ở xa có sử dụng Unicode hay không
mà sẽ chép tương ứng hàm dạng CallWindowProcA hay
CallWindowProcW), SASWndProc.
o Trong SASWndProc, cần sử dụng dữ liệu trong INJDATA nhưng đây là
một hàm callback nên tham số đầu vào không thể tùy biến, ta không thể
truyền tường minh dữ liệu này. Vì vậy, ở đây, ta đã biết được địa chỉ của dữ
liệu đầu vào INJDATA, và cả nội dung hàm SASWndProc đã được ghi vào
vùng nhớ bên tiến trình ở xa, ta phải thực hiện động tác ghi trực tiếp giá trị
biến nội tại sẽ lưu địa chỉ dữ liệu đầu vào INJDATA, bằng cách tìm trong
vùng nhớ ở xa đã ghi nội dung hàm SASWndProc từng DWORD một. Dĩ
nhiên biến nội tại này đã lưu một giá trị đặc biệt để có thể tìm ra.
o Sao chép nội dung hàm InjectFunc
tiểu trình thực hiện nội dung hàm InjectFunc: dùng o Tạo
SetWindowLong thay window procedure mới.
o Nếu thành công, công việc hoàn tất.
Hàm InjectFunc
Chức năng: tạo lớp con kế thừa, thay đổi hàm window procedure mới cho
cửa sổ SAS.
static DWORD WINAPI InjectFunc (INJDATA *pData)
Hàm window procedure mới chính là SASWindowProc. Ta không thể lấy
dữ liệu từ tiến trình ở xa (ví dụ như truy cập hàm SetWindowLong…) nên mọi dữ
liệu đầu vào phải chuẩn bị sẵn và “chích” vào tiến trình, tại đây, lần lượt các hàm sẽ
108
sử dụng các dữ liệu này. Ở đây, InjectFunc sử dụng địa chỉ hàm
SetWindowLong trong INJDATA
Ý nghĩa tham số:
pData: dữ liệu đầu vào, sẽ được giải thích ở phần sau.
Hàm GetSASWnd
Chức năng :lấy handle của cửa sổ SAS.
static HWND WINAPI GetSASWnd (INJDATA *pData)
Hàm SASWindowProc
LRESULT CALLBACK SASWindowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
Nếu đến đây mọi việc “đột nhập” đều suôn sẻ, các công việc sau đây sẽ được
thực hiện tiếp trong đoạn mã vừa sao chép (là nội dung các hàm nêu ở trên, các
• Lấy handle của cửa sổ SAS :
bước sau đều thực hiện trong không gian địa chỉ ảo của tiến trình ở xa):
hSASWnd = FindWindow("SAS Window class", "SAS window");
FindWindow là một hàm API khá hữu ích, được dùng để tìm handle của các
• Tạo lớp con kế thừa window procedure của cửa sổ SAS:
cửa sổ top-level nếu biết tên cửa sổ và tên lớp.
• Trong NewSASWindowProc(), bắt thông điệp WM_HOTKEY và trả về 1
SetWindowLong(hSASWnd, GWL_WNDPROC, NewSASWindowProc);
cho tổ hợp phím Ctrl – Alt – Del.
LRESULT CALLBACK NewSASWindowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_HOTKEY)
{
// Ctrl+Alt+Del
if (lparam == MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE))
return 1;
109
}
return CallWindowProc(OldSASWindowProc, hWnd, wParam, lParam);
}
Hình 3-9 Màn che mouse và bàn phím
110
3.3 Tương tác với hệ thống – Điều khiển danh sách các ứng
dụng đang chạy:
Trong quá trình thực hiện phần mềm, có một yêu cầu quản trị hệ thống là
người quản trị muốn biết tại thời điểm hiện tại, người dùng đang mở những ứng
dụng gì. Người quản trị có thể xem danh sách các ứng dụng đó, đồng thời có thể
thay đổi bằng cách thêm (mở một ứng dụng mới), bớt (tắt một ứng dụng đang
chạy). Yêu cầu này đòi hỏi cần phải tìm hiểu cơ chế quản lý cửa sổ trong hệ điều
hành Windows.
3.3.1 Các hàm dạng Enum_ và cơ chế gọi ngược (callback) của
Windows:
Có một số dữ liệu về hệ thống mà chúng ta khi cần truy cập trực tiếp sẽ rất
khó khăn, ví dụ như có bao nhiêu font chữ trên hệ thống ?, có bao nhiêu cửa sổ
đang họat động trên hệ thống ?... vì các dữ liệu dạng này đều do hệ thống nắm giữ,
và hệ thống không muốn chúng ta để ý nhiều về chi tiết quản lý của nó. Do đó, hệ
điều hành Windows cung cấp một số các hàm liệt kê sẽ giải đáp những thắc mắc
trên của chúng ta. Vấn đề còn lại là hệ thống không biết chúng ta sẽ xử lý như thế
nào với những dữ liệu mà nó cung cấp vì dữ liệu dạng này không được tường minh
(có thể không có hoặc có rất nhiều), hệ thống phải kiểm tra và trả về từng thành
phần dữ liệu một…
Câu trả lời là hệ điều hành Windows sẽ cung cấp một cơ chế gọi ngược
(callback). Nói một cách đơn giản, chúng ta sẽ thông báo với hệ thống rằng khi hệ
thống cung cấp các dữ liệu mà ta yêu cầu thì hãy xử lý theo những công việc mà ta
đề ra. Hàm mà chứa các công việc ta giao cho hệ thống làm được gọi là hàm gọi
ngược (callback function).
Một hàm gọi ngược là một hàm do ứng dụng của người dùng tự định nghĩa
và được thực thi bởi hệ điều hành mỗi khi có sự kiện liên quan đến hàm xảy ra.
111
3.3.2 EnumWindows
Để lấy được danh sách các ứng dụng đang chạy, ta sẽ sử dụng cơ chế gọi
ngược. Theo cơ chế gọi ngược, hệ điều hành Windows cung cấp một loạt các hàm
liệt kê bắt đầu bằng từ Enum (enumerate : liệt kê) như
EnumFontFamilliesEx, EnumForms và … EnumWindows.
EnumWindows chính là hàm ta cần:
Hàm EnumWindows
Chức năng: liệt kê tất cả cửa sổ top-level trên màn hình bằng cách trả về
handle của từng cửa sổ một cho một hàm gọi ngược của ứng dụng định nghĩa. Việc
liệt kê sẽ kết thúc khi đến cửa sổ cuối hoặc hàm gọi ngược trả về FALSE.
BOOL EnumWindows(
WNDENUMPROC lpEnumFunc,
LPARAM lParam
);
Ý nghĩa tham số:
[in]
lpEnumFunc : trỏ đến hàm gọi ngược.
lParam : giá trị do ứng dụng định nghĩa và chuyển cho hàm gọi ngược.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
Định nghĩa hàm gọi ngược của EnumWindows.
Chức năng: hàm gọi ngược của EnumWindows.
BOOL CALLBACK EnumWindowsProc(
HWND hwnd,
LPARAM lParam
);
Ý nghĩa tham số:
112
[in]
hwnd : handle của top-level windows.
lParam : giá trị do ứng dụng định nghĩa và chuyển cho hàm gọi ngược (là
tham số lParam trong hàm EnumWindows).
Giá trị trả về:
[out]
Để tiếp tục liệt kê cửa sổ, hàm phải trả về TRUE. Ngược lại, trả về FALSE.
Có một lưu ý nhỏ ở đây : ta vẫn có thể sử dụng hàm tương tự là
EnumDesktopWindows, là hàm liệt kê tất cả cửa sổ trên desktop. Tuy nhiên, ta có
thể lấy thiếu một số cửa sổ người dùng khi sử dụng hàm này. Ngược lại, hàm
EnumWindows lại có nhược điểm nhỏ là lấy dư các cửa sổ của hệ thống. Các cửa
sổ này không phải là các cửa sổ chúng ta cần, vì vậy ta phải có các thao tác loại bỏ
chúng đi.
3.3.3 Lấy danh sách các ứng dụng đang chạy:
Ta chỉ cần viết một hàm gọi ngược thực hiện các công việc sau:
o Nếu là cửa sổ gọi hàm EnumWindows, bỏ qua.
o Nếu là tiểu trình, bỏ qua.
o Nếu là cửa sổ ẩn, bỏ qua.
o Nếu là cửa sổ không có tiêu đề, bỏ qua.
o Nếu là cửa sổ Program Manager, bỏ qua.
o Nếu là cửa sổ đang chạy của người dùng (thỏa các điều kiện lọc), lưu lại tên.
Hàm ListWindows:
Chức năng : hàm gọi ngược thực hiện các công việc trên.
BOOL CALLBACK CTaskMgr::ListWindows(HWND hwnd, LPARAM lParam)
Ý nghĩa tham số và giá trị trả về: giống mô tả của hàm gọi ngược nêu ở trên.
Ở đây, tham số lParam là con trỏ trỏ đến cấu trúc WIN_TEXT_LIST do ta tự định
nghĩa để lưu lại tên các ứng dụng:
113
typedef struct {
HWND hWnd; //cua so ma ham CALLBACK thuoc ve
CStringArray sarWinText; //array luu window title
} WIN_TEXT_LIST;
Ý nghĩa cấu trúc khá đơn giản, như đã ghi trong phần chú thích của cấu trúc.
Đến đây, mục tiêu để ra đã hoàn tất, ta có thể tùy nghi sử dụng danh sách vào các
mục đích khác nhau, như bật và tắt ứng dụng đang chạy.
3.3.4 Tắt một ứng dụng đang chạy:
Việc tắt một ứng dụng đang chạy không khó nếu tắt biết rằng ta cần tắt cửa
sổ nào. Điều này nghe có vẻ quá hiển nhiên, ta có thể nói rằng “Tôi biết chứ ! Tôi
cần tắt cửa sổ này, tên cửa sổ đó là…”, nhưng đối với hệ điều hành Windows tên
cửa sổ không có một ý nghĩa gì cả. Điều hệ điều hành cần đó là handle của cửa sổ.
Do vậy ta sẽ viết một hàm đóng cửa sổ khi biết tên cửa sổ. Sau đó, mọi việc còn lại
quá đơn giản:
CWnd* wnd = CWnd::FromHandle(handle);
wnd->PostMessage(WM_CLOSE);
Ta chỉ làm cửa sổ tự gởi một thông điệp WM_CLOSE cho chính nó. Sau đó,
cửa sổ sẽ đóng. Ta không quá lo lắng việc đóng có thành công hay không vì đây
thông thường chỉ là các cửa sổ ứng dụng của người dùng, ngoài ra, nếu cửa sổ có
chứa dữ liệu mà người dùng chưa lưu (chẳng hạn, ta cần đóng cửa sổ Winword mà
người dùng đang gõ văn bản…) hệ điều hành Windows sẽ thông báo hỏi người
dùng. Người dùng có thể chọn không đóng cửa sổ. Khi ấy, ta sẽ yêu cầu đóng cửa
sổ vào lúc thích hợp khác.
Hàm CloseWindow
Chức năng: đóng cửa sổ khi biết tên của nó.
BOOL CTaskMgr::CloseWindow(LPCTSTR sWinTitle)
Hàm CloseWindow sẽ làm các công việc :
114
o Lấy handle cửa sổ desktop. Cửa sổ này là cửa sổ cha của mọi cửa sổ đang
chạy trên màn hình.
o Từ cửa sổ desktop, duyệt qua từng cửa sổ con của desktop.
o Nếu tìm thấy cửa sổ nào có tên phù hợp với cửa sổ ta cần tìm, đóng nó lại.
Hình 3-10 Tắt một ứng dụng đang chạy
3.3.5 Mở một ứng dụng
Việc mở một ứng dụng bằng mã lệnh thực thi không khó nếu ta sử dụng
đúng hàm API do Windows cung cấp. Ở đây, chỉ có điểm lưu ý nhỏ là ứng dụng
chạy nên nêu rõ đường dẫn tuyệt đối. Khi ta sử dụng đường dẫn tương đối, chẳng
hạn “control.exe”, hệ điều hành sẽ dò tìm ứng dụng trong:
(cid:131) Nơi chứa chương trình ứng dụng
(cid:131) Thư mục hiện hành
(cid:131) Thư mục system/system32
(cid:131) Thư mục Windows
(cid:131) Các thư mục liệt kê trong biến môi trường PATH
Vì vậy, có thể ứng dụng không thể được kích hoạt.
Hàm ShellExecute:
115
Chức năng: thực hiện một thao tác (mở, thực thi, tìm kiếm …) một tập tin
hay thư mục.
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
Ý nghĩa tham số:
[in]
hwnd : handle cửa sổ gọi.
lpOperation : thao tác lên tập tin:
edit : dùng một trình xử lý văn bản mở tập tin. Nếu lpFile không phải
là một tập tin văn bản, thao tác sẽ thất bại.
explore : mở thư mục lpFile.
find : tìm kiếm trên thư mục lpFile.
open : mở tập tin lpFile. lpFile có thể là một tập tin thực thi, văn bản,
hay thư mục.
print: in tập tin lpFile. Nếu lpFile không phải là một tập tin văn bản,
thao tác sẽ thất bại.
NULL : Các phiên bản trước Windows 2000: tên thao tác mặc định
quy định trong registry. Nếu không, thao tác “open” sẽ được dùng.
Các phiên bản từ Windows 2000: tên thao tác mặc định quy
định trong registry. Nếu không, thao tác “open” sẽ được dùng. Nếu vẫn không
được, hệ điều hành sẽ dùng thao tác đầu tiên đăng ký vào danh sách trong registry.
lpFile: tên tập tin hay thư mục.
116
lpParameters : tham số dành cho lpFile nếu lpFile là một tập tin thực thi.
Nếu lpFile là một tập tin văn bản, lpParameters nên đặt là NULL.
lpDirectory : đường dẫn tuyệt đối.
nShowCmd :
SW_HIDE
Giấu cửa sổ.
SW_MAXIMIZE
Phóng to hết cỡ cửa sổ.
SW_MINIMIZE
Thu nhỏ cửa sổ.
SW_RESTORE
Phục hồi cửa sổ về kích thước mặc định của nó.
SW_SHOW
Hiện cửa sổ theo kích thước mặc định của nó.
SW_SHOWDEFAULT
Đặt trạng thái mặc định của cửa sổ khi mở là hiện ra.
SW_SHOWMAXIMIZED
Hiện và phóng to hết cỡ cửa sổ.
SW_SHOWMINIMIZED
Hiện và thu nhỏ cửa sổ.
SW_SHOWMINNOACTIVE
Thu nhỏ cửa sổ nhưng không kích hoạt nó.
SW_SHOWNA
Hiện cửa sổ như trạng thái mà nó đã quy định.
SW_SHOWNOACTIVATE
Hiện cửa sổ nhưng không kích hoạt nó.
SW_SHOWNORMAL
Hiện và kích hoạt cửa sổ.
Giá trị trả về:
117
[out]
Nếu thành công, trả về giá trị lớn hơn 32.
Nếu thất bại, trả lỗi.
Áp dụng vào chương trình:
(int)ShellExecute(NULL, "open", lpFile, lpParam, lpPath, SW_SHOW);
Với lpFile, lpParam, lpPath lần lượt là các giá trị lpFile, lpParameters,
lpDirectory đã giải thích ở trên. Lưu ý rằng, ta phải ép kiểu “(int)” khi lấy kết quả vì
nguyên hàm của hàm có trị trả về là HINSTANCE. Thực chất, kiểu trị trả về như
thế để tương thích ngược với các ứng dụng 16-bit cũ.
Hình 3-11 Mở một ứng dụng
3.4 Điều khiển máy tính từ xa:
Trong quá trình thực hiện phần mềm, có một yêu cầu quản trị hệ thống là
người quản trị cần log out, restart và shutdown một máy tính hoặc các máy đang
hoạt động. Điều này có thể thực hiện thông qua các hàm API hệ thống của
Windows nhưng trước hết, ta cần phải biết thêm cơ chế đăng nhập của hệ điều hành
Windows.
118
3.4.1 Cơ chế đăng nhập:
3.4.1.1 Winlogon:
Cơ chế đăng nhập của Windows, Winlogon được thiết kế theo mô hình đăng
nhập tương tác gồm 3 phần : thành phần thực thi (“winlogon.exe”), thư viện liên kết
động “Chứng thực và nhận dạng theo cơ chế đồ họa” (Graphical Identification and
Authentication GINA) (“msgina.dll”), và các thành phần mạng. Để biết thêm về
GINA, xem Phụ lục GINA stub – kỹ thuật xây dựng.
Quá trình đăng nhập được mô tả như sau:
Người dùng đăng nhập hệ thống Người dùng sử dụng tài nguyên hệ thống Hệ thống cấp một thẻ bài truy cập (access token) cho người dùng
Dựa vào thẻ bài, hệ thống quyết định xem người dùng có được sử dụng tài nguyên hay không.
Người dùng thóat khỏi hệ thống Hệ thống chấp nhận và hủy thẻ bài
Hình 3-12 Quá trình đăng nhập
* thẻ bài truy cập (access token):
Một thẻ bài truy cập chứa đựng thông tin bảo mật của session đăng nhập. Hệ
thống tạo thẻ bài khi người dùng đăng nhập, và mỗi tiến trình thực thi dưới quyền
của người dùng đều có một bản sao của thẻ bài. Thẻ bài xác định người dùng, nhóm
người dùng và đặc quyền của người dùng. Hệ thống dùng thẻ bài để kiểm soát việc
truy cập đến các đối tượng bảo mật và khống chế các hoạt động liên quan đến hệ
119
thống của người dùng. Tùy thuộc vào đặc quyền của người dùng, mà mức độ khống
chế cao hay thấp. Chẳng hạn, quản trị viên có toàn quyền đối với hệ thống.
3.4.1.2 Phân tích:
• Lấy thẻ bài của người dùng.
• Với thẻ bài, kiểm tra xem người dùng có đặc quyền log out, restart,
Vậy việc ta phải làm là :
• Nếu có, bật đặc quyền lên (cho phép các tiến trình sử dụng đặc quyền để
shutdown hay không.
• Nếu thành công. công việc hoàn tất.
thực hiện thao tác log out, restart, hay shutdown trên hệ thống).
3.4.2 Các hàm API hệ thống được sử dụng:
3.4.2.1 OpenProcessToken
Chức năng : mở thẻ bài truy cập của tiến trình. khi biết handle.
BOOL OpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle
);
Ý nghĩa tham số:
[in]
ProcessHandle : handle của tiến trình.
DesiredAccess : quyền truy cập yêu cầu.
[out]
TokenHandle : handle của thẻ bài.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0.
120
Nếu thất bại, trả về 0. Gọi GetLastError để biết lỗi.
3.4.2.2 LookupPrivilegeValue
Chức năng : lấy số định dạng cục bộ duy nhất (LUID). LUID là một giá trị
64 bit có ý nghĩa duy nhất trên hệ điều hành mà phát sinh ra số cho đến khi hệ thống
khởi động lại.
BOOL LookupPrivilegeValue(
LPCTSTR lpSystemName,
LPCTSTR lpName,
PLUID lpLuid
);
Ý nghĩa tham số:
lpSystemName : tên hệ thống mà đặc quyền sẽ được lấy.
lpName : tên đặc quyền.
[out]
lpLuid : LUID của hệ thống.
Giá trị trả về
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
3.4.2.3 AdjustTokenPrivileges
Chức năng: bật hay tắt đặc quyền của một thẻ bài truy cập, phải có truy cập
TOKEN_ADJUST_PRIVILEGES.
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle,
BOOL DisableAllPrivileges,
PTOKEN_PRIVILEGES NewState,
DWORD BufferLength,
PTOKEN_PRIVILEGES PreviousState,
121
PDWORD ReturnLength
);
Ý nghĩa tham số:
[in]
TokenHandle : handle của thẻ bài cần bật/tắt đặc quyền.
DisableAllPrivileges : TRUE, tắt tất cả các đặc quyền.
FALSE, chỉnh sửa các đặc quyền dựa trên thông tin của NewState.
NewState : trỏ đến cấu trúc TOKEN_PRIVILEGES:
typedef struct _TOKEN_PRIVILEGES {
DWORD PrivilegeCount; // số đặc quyền
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; // mảng các
LUID
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
trong đó cấu trúc LUID_AND_ATTRIBUTES :
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid; // số LUID
DWORD Attributes.; // thuộc tính của LUID
} LUID_AND_ATTRIBUTES,
*PLUID_AND_ATTRIBUTES
với Attributes tổ hợp các giá trị sau:
Giá trị
Ý nghĩa
SE_PRIVILEGE_ENABLED Đặc quyền bật.
SE_PRIVILEGE_REMOVED Gở bỏ đặc quyền.
None Tắt đặc quyền.
Bảng 3-3 Giá trị của biến Attributes
BufferLength : kích thước theo byte của vùng đệm chứa PreviousState. Giá
trị này là 0 nếu PreviousState là NULL.
122
PreviousState : tương tự NewState, nhưng cho biết trạng thái trước của đặc
quyền cần chỉnh sửa.
ReturnLength : trả về kích thước thật của vùng đệm chứa PreviousState.
NULL nếu PreviousState là NULL.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0
Nếu thất bại, trả về 0. Gọi GetLastError để biết lỗi.
3.4.2.4 ExitWindowsEx
Chức năng : thực hiện log out, restart, shutdown.
BOOL ExitWindowsEx(
UINT uFlags,
DWORD dwReason
);
Ý nghĩa tham số:
[in]
uFlags: cờ hiệu, là tổ hợp những giá trị sau:
Giá trị Ý nghĩa
Đóng tất cả các cửa sổ và đăng xuất EWX_LOGOFF người dùng
Shutdown hệ thống và tắt máy. Hệ
thống phải hỗ trợ tính năng tắt máy. EWX_POWEROFF Tiến trình gọi phải có đặc quyền
SE_SHUTDOWN_NAME.
Shutdown hệ thống và khởi động lại
EWX_REBOOT máy. Tiến trình gọi phải có đặc quyền
SE_SHUTDOWN_NAME.
123
Shutdown hệ thống ở thời điểm an
toàn nhưng không tắt máy. Tiến trình EWX_SHUTDOWN gọi phải có đặc quyền
SE_SHUTDOWN_NAME.
Bảng 3-4 Giá trị cờ hiệu
Tham số tùy chọn :
Giá trị Ý nghĩa
Ép các tiến trình kết thúc. Cờ hiệu
này có thể làm ứng dụng mất dữ liệu.
EWX_FORCE Windows XP: Nếu máy bị khóa và
cờ không đặct, tiến trình shutdown sẽ
thất bại.
Ép các tiến trình kết thúc nếu chúng
bỏ qua thông điệp yêu cầu kết thúc
thông thường
WM_QUERYENDSESSION hay
EWX_FORCEIFHUNG WM_ENDSESSION. cờ sẽ bỏ qua
nếu đã có EWX_FORCE.
Windows NT and
Windows Me/98/95: không hỗ trợ.
Bảng 3-5 Giá trị cờ hiệu tùy chọn
dwReason: lý do shutdown, xem thêm trong MSDN để biết chi tiết.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0. Tuy thế, điều này vẫn không chắc rằng thao
tác có thành công hay không.
124
Nếu thất bại, trả về 0. Gọi GetLastError để biết lỗi.
3.4.3 Cài đặt :
Áp dụng các hàm API trên để thực hiện các công việc đề ra ở 3.4.1.2 Phân
tích:
BOOL CShutdownClient::ShutdownSystem(int iOption)
Hàm có tác dụng thực hiện shutdown, restart, log out trong một khoảng thời
gian xác định.
Có một lưu ý nhỏ là trong quá trình làm phần mềm, ta gặp rắc rối là khi thực
thi thành công hàm ShutdownSystem, ta vẫn không chắc là thao tác ta yêu cầu
trên máy khách có thành công hay không. Vì vậy, bên phía Server chỉ biết được
điều này khi Server mất liên lạc với chương trình bên Client. Việc còn lại là ta chỉ
cần thông báo cho Server biết lỗi thực thi không thành công chứ không bao giờ gởi
báo thành công.
Hình 3-13 Điều khiển hoạt động máy tính từ xa
125
3.5 Tương tác hệ thống – Điều khiển các dịch vụ có trên hệ
thống:
Trong quá trình thực hiện phần mềm, có một yêu cầu quản trị hệ thống là
người quản trị muốn biết tại thời điểm hiện tại, máy khách đang hoạt động những
dịch vụ (service) gì. Người quản trị có thể xem danh sách các dịch vụ đó, đồng thời
có thể thay đổi bằng cách thêm (mở một dịch vụ mới), bớt (tắt một dịch vụ đang
chạy). Yêu cầu này đòi hỏi cần phải tìm hiểu cơ chế quản lý dịch vụ trong hệ điều
hành Windows.
3.5.1 Dịch vụ
3.5.1.1 Khái niệm:
Ứng dụng có khả năng hoạt động trong một khỏang thời gian dài trong một
session của hệ điều hành Windows được gọi là dịch vụ. Các dịch vụ có thể tự động
chạy lên mỗi khi máy khởi động, có thể dừng và khởi động lại, và không đưa ra
giao diện với người dùng. Dịch vụ thường được sử dụng trên server hoặc bất cứ
máy nào cần các tính năng hoạt động lâu dài nhưng không cần can thiệp bởi người
dùng.
3.5.1.2 Loại dịch vụ:
Ta không đi quá sâu vào các dịch vụ cấp thấp. Ta chỉ quan tâm các dịch vụ
dạng ứng dụng chạy là 2 loại Win32OwnProcess và Win32ShareProcess.
3.5.1.3 Vòng đời của dịch vụ:
Một dịch vụ trải qua nhiều trạng thái trong vòng đời hoạt động của nó. Trước
hết, dịch vụ được cài đặt trong hệ thống mà nó sẽ chạy. Quá trình này thực thi bộ
cài đặt của dịch vụ và nạp dịch vụ vào trong Service Control Manager (Bộ Quản lý
Điều khiển Dịch vụ). Service Control Manager là một công cụ do hệ điều hành
Windows cung cấp để quản trị các dịch vụ.
126
Sau khi dịch vụ được nạp, nó phải được khởi động (start). Khởi động dịch vụ
cho phép nó hoạt động. Một dịch vụ đang hoạt động (running) có thể tồn tại ở trạng
thái này cho đến khi nó được ngưng lại (stop) hoặc dừng hẳn (pause) hay máy
shutdown. Dịch vụ có thể tồn tại dưới 3 trạng thái căn bản : Đang hoạt động
(Running), Ngưng (Paused), hay Dừng (Stopped). Dịch vụ còn báo về các trạng thái
chuyển (pending) của nó: Tiếp tục Chuyển (ContinuePending), Chuyển Ngưng
(PausePending), Chuyển Khởi động (StartPending), hay Chuyển Dừng
(StopPending). Các trạng thái chuyển cho biết lệnh nào mới vừa được kích hoạt,
nhưng chưa thực thi xong.
Ngoài ra, dịch vụ cần thêm thông tin về trạng thái khởi động của nó. Một số
dịch vụ rất cần thiết cho hệ thống (như dịch vụ DHCP), còn một số thì không.
Người sử dụng máy có thể cần kích hoạt tự động (Automatic), kích hoạt bằng tay
(Manual), hay vô hiệu hóa (Disabled) dịch vụ. Vì vậy, dịch vụ có 3 trạng thái khởi
động (trạng thái dịch vụ khi máy vừa khởi động xong) là Tự động (Automatic),
Bằng tay (Manual), Vô hiệu (Disabled).
Việc điều khiển các dịch vụ đang hoạt động chính là xem danh sách các dịch
vụ, thay đổi 3 trạng thái hoạt động là Đang hoạt động (Running), Ngưng (Paused),
hay Dừng (Stopped), và 3 trạng thái khởi động là : Tự động (Automatic), Bằng tay
(Manual), Vô hiệu (Disabled). Tuy nhiên, với yêu cầu ở đầu mục, ta chỉ cần điều
khiển 2 trạng thái hoạt động là Running và Stopped, và 3 trạng thái khởi động đã
nêu là đủ.
3.5.2 Điều khiển các dịch vụ đang hoạt động trên hệ thống:
Qua kiến thức khái quát về dịch vụ ở 3.5.1, ta có thể thấy rằng để truy xuất
đến các dịch vụ đang chạy trên hệ thống, ta phải thông qua Service Control
Manager. Đây là cách chung nhất, và có vẻ là cách khả thi duy nhất trên Visual C++
do VC++ 6.0 không hỗ trợ về truy xuất liên quan đến dịch vụ.
127
3.5.2.1 Các hàm API sử dụng :
3.5.2.1.1 OpenSCManager:
Chức năng : thiết lập kết nối đến Service Control Manager trên máy tính và
mở cơ sở dữ liệu của Service Control Manager.
SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName,
LPCTSTR lpDatabaseName,
DWORD dwDesiredAccess
);
Ý nghĩa tham sô:
[in]
lpMachineName : tên máy tính. Nếu là NULL, sẽ mở chính máy tính cục
bộ này.
lpDatabaseName : tên của cơ sở dữ liệu Service Control Manager cần được
mở.
dwDesiredAccess : quyền truy cập mong muốn, xem chi tiết trong MSDN
về các quyền truy cập.
Giá trị trả về:
[out]
Nếu thành công, trả về handle của cơ sở dữ liệu Service Control Manager
được mở.
Nếu thất bại, trả về NULL. . Để biết lỗi, gọi GetLastError.
3.5.2.1.2 EnumServicesStatus
Chức năng: đếm và lấy thông tin về các dịch vụ trong một cơ sở dữ liệu
Service Control Manager được mở.
BOOL EnumServicesStatus(
SC_HANDLE hSCManager,
DWORD dwServiceType,
128
DWORD dwServiceState,
LPENUM_SERVICE_STATUS lpServices,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded,
LPDWORD lpServicesReturned,
LPDWORD
);
Ý nghĩa tham số:
[in]
hSCManager: handle của cơ sở dữ liệu Service Control Manager
được mở, do OpenSCManager trả về khi mở thành công.
dwServiceType : loại dịch vụ cần mở
dwServiceState : trạng thái loại dịch vụ cần liệt kê
[out]
lpServices : trỏ đến cấu trúc ENUM_SERVICE_STATUS chứa thông tin
dịch vụ:
typedef struct _ENUM_SERVICE_STATUS {
LPTSTR lpServiceName; // tên đăng ký của dịch vụ
LPTSTR lpDisplayName; //tên của dịch vụ
SERVICE_STATUS ServiceStatus;
} ENUM_SERVICE_STATUS,
*LPENUM_SERVICE_STATUS;
ServiceStatus : là cấu trúc SERVICE_STATUS
typedef struct _SERVICE_STATUS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
129
DWORD dwCheckPoint;
DWORD dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;
dwServiceType : loại dịch vụ.
dwCurrentState :
Giá trị Ý nghĩa
SERVICE_CONTINUE_PENDING Tiếp tục chuyển.
SERVICE_PAUSE_PENDING Chuyển ngưng.
SERVICE_PAUSED Dịch vụ ngưng.
SERVICE_RUNNING Dịch vụ đang chạy.
SERVICE_START_PENDING Dịch vụ đang khởi động.
SERVICE_STOP_PENDING Dịch vụ đang dừng.
SERVICE_STOPPED Dịch vụ dừng hẳn.
Bảng 3-6 Tình trạng hiện tại
dwControlsAccepted
Mã điều khiển Ý nghĩa
Dịch vụ là một thành phần mạng
chấp nhận thay đổi trong SERVICE_ACCEPT_NETBINDCHANGE binding mà không cần dừng hay
khởi động lại.
Dịch vụ có thể đọc lại các tham
SERVICE_ACCEPT_PARAMCHANGE số khởi tạo mà không cần dừng
hay khởi động lại.
Dịch vụ có thể ngưng hay tiếp SERVICE_ACCEPT_PAUSE_CONTINUE tục.
SERVICE_ACCEPT_SHUTDOWN Dịch vụ được thông báo khi hệ
130
thống shutdown.
SERVICE_ACCEPT_STOP Dịch vụ có thể dừng.
Bảng 3-7 Loại điều khiển chấp nhận
dwWin32ExitCode : mã lỗi khi có một lỗi xảy ra khi đang khởi động
hay đang dừng.
dwServiceSpecificExitCode : lỗi thực thi do dịch vụ tự định nghĩa.
dwCheckPoint : giá trị tăng dần khi dịch vụ trải qua lần lược các quá
trình khởi động, dừng, ngưng, hay tiếp tục.
dwWaitHint : thời gian dự đoán cho một thao tác khởi động, dừng,
ngưng, hay tiếp tục, tính theo mili giây.
cbBufSize : vùng đệm chứa thông tin dịch vụ từ lpServices.
[out]
pcbBytesNeeded : số byte cần thêm để lấy các mục dịch vụ còn sót (không
chứa đủ trong cbBufSize).
lpServicesReturned : số lượng các mục dịch vụ lấy được.
[in, out]
lpResumeHandle : handle bắt đầu của dữ liệu chứa các mục dịch vụ còn sót
lại.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
3.5.2.1.3 OpenService
Chức năng: mở một dịch vụ có sẵn.
SC_HANDLE OpenService(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
DWORD dwDesiredAccess
131
);
Ý nghĩa tham số
[in]
hSCManager : handle của một cơ sở dữ liệu Service Control Manager được
mở. Hàm OpenSCManager trả về handle này.
lpServiceName : tên của service được mở, tên này không dài quá 256 ký tự.
Cơ sở dữ liệu Service Control Manager phân biệc chữ hoa chữ thường, nhưng so
sánh tên của các dịch vụ thì không. Các ký tự “/” và “\” đều không dùng cho tên của
dịch vụ.
dwDesiredAccess : quyền truy cập dịch vụ mong muốn.
Giá trị trả về
[out]
Nếu thành công, trả về handle của dịch vụ được mở.
Nếu thất bại, trả về NULL. Để biết lỗi, gọi GetLastError.
3.5.2.1.4 StartService
Chức năng : kích hoạt một dịch vụ.
BOOL StartService(
SC_HANDLE hService,
DWORD dwNumServiceArgs,
LPCTSTR* lpServiceArgVectors
);
Ý nghĩa tham số:
hService : handle dịch vụ đã mở bằng OpenService hay CreateService, và
phải có quyền truy cập SERVICE_START.
dwNumServiceArgs : số đối số chuỗi truyền cho dịch vụ.
lpServiceArgVectors : mảng các đối số chuỗi. Dịch vụ driver không nhận
các đối số này. Nếu không cần đối số cho dịch vụ, biến đặt là NULL.
Giá trị trả về:
132
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
3.5.2.1.5 ControlService
Chức năng : gởi mã điều khiển đến dịch vụ.
BOOL ControlService(
SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus
);
Ý nghĩa tham số:
hService : handle dịch vụ đã mở bằng OpenService hay CreateService, và
phải có quyền truy cập SERVICE_START.
dwControl : mã điều khiển.
lpServiceStatus: trỏ đến cấu trúc SERVICE_STATUS nhận thông tin tình
trạng mới nhất của dịch vụ, xem thêm 3.5.2.12 EnumServicesStatus để biết thêm
về cấu trúc.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
3.5.2.1.6 ChangeServiceConfig:
Chức năng : thay đổi các tham số cấu hình của dịch vụ.
BOOL ChangeServiceConfig(
SC_HANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
133
LPCTSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCTSTR lpDependencies,
LPCTSTR lpServiceStartName,
LPCTSTR lpPassword,
LPCTSTR lpDisplayName
);
Ý nghĩa tham số
[in]
hService : handle dịch vụ đã mở bằng OpenService hay CreateService
dwServiceType : loại dịch vụ, xem 3.5.2.1.2 EnumServicesStatus để biết
thêm.
dwStartType : loại trạng thái khởi động.
dwErrorControl : lỗi điều khiển, để SERVICE_NO_CHANGE nếu không
muốn thay đổi điều khiển lỗi đang có.
lpBinaryPathName : tên tập tin nhị phân thực thi của dịch vụ.
lpLoadOrderGroup : tên nhóm thứ tự nạp mà dịch vụ là thành viên.
lpdwTagId : giá trị thẻ ghi duy nhất trong nhóm nạp.
lpDependencies : dịch vụ hay nhóm các dịch vụ trong nhóm nạp cần tải
trước khi dịch vụ có thể khởi động.
lpServiceStartName : tên tài khỏan mà dịch vụ chạy.
lpPassword : mật khẩu.
lpDisplayName : tên giao tiếp của dịch vụ với các ứng dụng.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
3.5.2.1.7 CloseServiceHandle
134
Chức năng : đóng handle được mở cho cơ sở dữ liệu Service Control
Manager hay đối tượng dịch vụ.
BOOL CloseServiceHandle(
SC_HANDLE hSCObject
);
Ý nghĩa tham số:
[in]
hSCObject : handle được mở cho cơ sở dữ liệu Service Control Manager
hay đối tượng dịch vụ cần đóng.
Giá trị trả về:
[out]
Nếu thành công, trả về khác 0.
Nếu thất bại, trả về 0. Để biết lỗi, gọi GetLastError.
3.5.2.2 Cài đặt :
Dựa vào các hàm API nêu ở 3.5.1, ta sẽ thực hiện các cài đặt
3.5.2.2.1 Xem danh sách các dịch vụ :
Các công việc cần làm:
o Mở cơ sở dữ liệu SERVICES_ACTIVE_DATABASE của Service Control
Manager.
o Lấy danh sách các dịch vụ.
o Đóng cơ sở dữ liệu lại.
Hàm cài đặt
BOOL CTaskMgr::GetServiceList(ENUM_SERVICE_STATUS* &pSrvList,
DWORD& nCount)
Có lưu ý cho hàm GetServiceBufferSizeNeeded. Hàm cài đặt này
có tác dụng trả về số byte thực sự cần để lưu các thông tin về các dịch vụ.
135
Hình 3-14 Xem danh sách các dịch vụ
3.5.2.2.2 Đổi trạng thái khởi động của dịch vụ :
Thực hiện các công việc sau:
o Mở cơ sở dữ liệu Service Control Manager.
o Mở dịch vụ
o Thay đổi trạng thái khởi động là SERVICE_AUTO_START hay
SERVICE_DEMAND_START hay SERVICE_DISABLED.
o Đóng các handle lại.
Hàm cài đặt ChangeWaytoStartup
int CTaskMgr::ChangeWaytoStartup(CString sServiceName, DWORD
dwStartType)
136
Hình 3-15 Đổi trạng thái khởi động
3.5.2.2.3 Khởi động dịch vụ:
Thực hiện các công việc sau:
o Mở cơ sở dữ liệu Service Control Manager.
o Mở dịch vụ
o Khởi động dịch vụ.
o Đóng các handle lại.
Hàm cài đặt StartService
int CTaskMgr::StartService(CString sServiceName)
3.5.2.2.4 Dừng dịch vụ:
Thực hiện các công việc sau:
o Mở cơ sở dữ liệu Service Control Manager.
o Mở dịch vụ
o Dừng dịch vụ.
o Đóng các handle lại.
Hàm cài đặt StopService
int CTaskMgr::StopService(LPCTSTR sServiceName)
137
Hình 3-16 Khởi động / tắt dịch vụ
Hoàn tất yêu cầu ban đầu.
Chương 4 Các công nghệ :
Trong ba công nghệ truyền hình ảnh, âm thanh chúng em đã nghiên cứu và
trình bày trong chương này đều có những ưu và nhược điểm riêng:
RFB H323 Windows Media
Encoder (WME)
Khả năng ứng dụng Là một bộ phát Ưu điểm Giải quyết triệt để
rộng rãi trên nhiều hệ triển phần mềm của vấn đề quan sát màn
điều hành khác nhau. Windows, WME hình từ xa vì nghi
Với khả năng tích hợp tích hợp chặt chẽ thức giao tiếp với
mạnh mẽ, H323 có thể với hệ điều hành hai đầu cuối là là
hỗ trợ nhiều công nghệ Windows, đưa ra vùng đệm khung cho
các khả năng mã màn hình. Nghi thức truyền hình ảnh âm
hóa và giải mã âm mã nguồn mở, hỗ trợ thanh khác nhau
thanh hình ảnh theo đa nền. (H261, H263…). Công
dòng rất hiệu quả. nghệ mã nguồn mở.
Khuyết điểm Khả năng ứng dụng Các bản phát hành trên Đòi hỏi tối đa việc
các lĩnh vực khác Windows còn nhiều hỗ trợ về hệ điều
138
hành trong việc hạn chế và lỗi, chưa khá hạn chế, nghi
truyền gởi (phải là giải quyết triệt để việc thức hầu như chỉ
hệ điều hành hỗ trợ trên Windows dành riêng cho ứng
Windows các phiên (còn “bóng dáng” của dụng điều khiển máy
bản mới thì hỗ trợ Linux trong việc biên tính từ xa.
hiệu quả cho dịch).
WME).
Bảng 4-1 So sánh các công nghệ nghiên cứu
Qua các sơ lược về ưu khuyết điểm trên, chúng em chọn nghi thức RFB để
thực hiện việc cài đặt, hai công nghệ còn lại chỉ dừng ở mức tìm hiểu và nghiên
cứu.
4.1 RFB
4.1.1 Giới thiệu:
RFB (“remote framebuffer”) là một nghi thức đơn giản để truy xuất đến giao
diện người dùng đồ họa. Vì nó làm việc ở mức vùng đệm khung, nghi thức
tương thích với mọi ứng dụng và hệ thống theo dạng “cửa sổ”, gồm cả X11,
Window.
Đầu cuối ở xa là nơi người dùng sử dụng (chẳng hạn màn hình kèm bàn
phím và có hay không chuột) được gọi là RFB client. Đầu cuối nơi những thay
đổi trên vùng đệm khung phát sinh (chẳng hạn các ứng dụng và hệ thống dạng
“cửa sổ”) gọi là RFB server.
139
Hình 4-1 Giới thiệu nghi thức RFB
RFB là nghi thức dành cho thin client. Điều đáng lưu ý trong thiết kế nghi
thức RFB là có rất ít yêu cầu về hệ thống cho client. Do đó, client có thể chạy
trên hầu hết các loại phần cứng khác nhau, công việc cài đặt, xây dựng client
càng đơn giản càng tốt.
Nghi thức xây dựng cho client ở dạng stateless. Nếu nghi thức ngắt kết nối từ
một server cho trước và sau đó kết nối lại với server, trạng thái của giao diện
người dùng được giữ nguyên. Hơn nữa, một đầu cuối client khác cũng có thể kết
nối vào cùng RFB server. Ở đầu cuối mới, người dùng cũng sẽ thấy chính xác
cùng một giao diện người dùng đồ họa như đầu cuối kia. Khi có kết nối mạng
thích hợp, người dùng có thể truy cập, các ứng dụng cá nhân của họ, và trạng
thái của ứng dụng đó sẽ giữ gìn giữa các truy xuất từ các vị trí khác nhau. Điều
này cung cấp cho người dùng một cách nhìn thân thiện, chuẩn mực về kiến trúc
máy tính khi họ đi đến bất cứ đâu.
4.1.2 Nghi thức xuất ra màn hình:
Phần xuất của nghi thức dựa trên nguyên tắc đồ họa đơn nhất : “in một hình
chữ nhật dữ liệu điểm ảnh (pixel) tại một vị trí x, y cho trước”. Nhìn sơ qua,
điều này có vẻ không phải là cách làm hiệu quả để vẽ nhiều thành phần giao
diện người dùng. Tuy nhiên, áp dụng nhiều thuật tóan mã hóa khác nhau cho dữ
liệu điểm ảnh lại đem đến cho chúng ta sự linh động rất cao trong việc điều
140
chỉnh các thông sô như băng thông mạng, tốc độ vẽ bên client và tốc độ xử lý
của server.
Một lọat các hình chữ nhật như trên tạo nên một cập nhật vùng đệm khung
(hay đơn giản là một cập nhật). Một cập nhật đại diện cho sự thay đổi từ trạng
thái của một vùng đệm khung hiệu lực sang trạng thái khác, do vậy trong một
khía cạnh nào đó nó khá giống với khung hình của video. Các hình chữ nhật
trong một cập nhật thông thường rời rạc nhưng điều này cũng không đáng lưu ý
lắm.
Nghi thức cập nhật được điều khiển bởi người dùng. Có nghĩa là, một cập
nhật chỉ gởi từ một server đến một client để đáp ứng một yêu cầu rõ ràng từ phía
người dùng. Điều này cho phép nghi thức có thay đổi tùy nghi về chất lượng
truyền. Client và đường mạng càng chậm, tần suất cập nhật càng thấp. Với các
ứng dụng điển hình, những thay đổi trên cùng một vùng của vùng đệm khung
thường có khynh hướng xảy ra ngay lần lượt. Với một client chậm và/hay một
đường mạng chậm, các trạng thái thay đổi nhanh có thể bỏ qua, đưa đến kết quả
là có ít lưu thông mạng hơn và có ít đường vẽ trên client hơn.
4.1.3 Nghi thức nhập thông tin:
Phần nhập của nghi thức dựa trên mô hình máy trạm chuẩn gồm một bàn
phím và một thiết bị trỏ đa nút (thông thường là chuột). Các sự kiện nhập chỉ
đơn giản gởi cho server từ client khi người dùng nhấn phím hoặc nút trỏ, hay bất
cứ khi nào thiết bị trỏ di chuyển. Các sự kiện đầu vào cũng có thể tổng hợp từ
các thiết bị nhập/xuất không chuẩn. Ví dụ, một dụng cụ nhận dạng chữ viết tay
dạng cây viết có thể phát sinh các sự kiện bàn phím.
4.1.4 Trình bày dữ liệu điểm ảnh:
Giao tiếp ban đầu của RFB client và server liên quan đến một quá trình thỏa
thuận về định dạng và mã hóa cho dữ liệu điểm ảnh sẽ gởi. Quá trình thỏa thuận
này được thiết kế nhằm mục đích cho họat động xử lý ở client càng dễ dàng
càng tốt. Điều lưu ý là server phải luôn có thể đáp ứng mọi định dạng mà người
141
dùng mong muốn. Tuy nhiên client có thể tùy nghi với nhiều dạng và mã hóa
khác nhau, nó có thể chọn dạng mà dễ dàng cho server xử lý hơn.
Định dạng điểm ảnh là việc trình bày các màu riêng biệt của các giá trị điểm
ảnh. Định dạng điểm ảnh phổ biến nhất là 24-bit và 16-bit “màu thực”, mà trong
các trường bit giá trị điểm ảnh biên dịch trực tiếp thành các cường độ của sắc
đỏ, xanh lá cây và xanh da trời, và 8-bit “bản màu” nơi một quá trình ánh xạ tùy
ý có thể dùng để biên dịch các giá trị điểm ảnh sang các cường độ RGB (Red
Green Blue).
Mã hóa là việc làm thế nào một chữ nhật dữ liệu điểm ảnh sẽ gởi trên đường
truyền. Mỗi chữ nhật dữ liệu điểm ảnh được đính trước bằng một header cho
biết vị trí X, Y của hình chữ nhật trên màn hình, bề rộng và chiều cao của hình
chữ nhật, và loại mã hóa xác định dạng mã hóa của dữ liệu điểm ảnh. Dữ liệu
theo đó sẽ dùng đúng loại mã hóa đã xác định.
4.1.5 Các mở rộng cho nghi thức:
Nghi thức có thể mở rộng bằng việc thêm các loại mã hóa mới. Các loại mã
hóa được định nghĩa hịên tại là Raw, CopyRect, RRE, CoRRE, Hextile và ZRLE.
Trong thực tế, chúng ta chỉ dùng ZRLE, Hextile và CopyRect vì chúng cung cấp
khả năng nén tốt nhất cho một máy tính điển hình.
Thêm vào các mã hóa thật, client có thể yêu cầu một “mã hóa giả” để khai
báo với server rằng nó có hỗ trợ một mở rộng của nghi thức. Một server không
hỗ trợ phần mở rộng sẽ bỏ qua mã hóa giả trên. Chú ý rằng điều này có nghĩa là
client phải ngầm hiểu là server không hỗ trợ phần mở rộng cho đến khi nó nhận
được xác nhận về mở rộng đó của server.
Điều quan trọng là loại mã hóa và mã hóa giả khác không gây xung đột. Để
tránh điều đó, phiển bản nghi thức RFB và các loại mã hóa được RealVNC Ltd
chứng thực và duy trì.
142
4.1.6 Các thông điệp nghi thức:
Nghi thức RFB có thể họat động trên mọi tầng vận chuyển tin cậy, dựa trên
luồng byte hay thông điệp. Có hai phần trong nghi thức, một pha bắt tay khởi
tạo theo sau một giao tiếp nghi thức thông thường.
Bắt tay khởi tạo bao gồm các thông điệp về Phiên bản Nghi thức, Bảo mật,
Khởi tạo bên Client và Khởi tạo bên Server, sẽ được mô tả sau. Chú ý cả server
và client đều gởi thông điệp Phiên bản Nghi thức.
Nghi thức tiến hành trong phần giao tiếp thông thường sau thông điệp Khởi
tạo bên Server. Ở phần này, client có thể gởi bất cứ thông điệp nào mà nó muốn,
và có thể nhận được những thông điệp kết quả từ server. Mọi thông điệp đó đều
bắt đầu bằng một byte loại thông điệp, theo sau là dữ liệu.
Bảng mô tả thông điệp sau đây sử dụng các dạng dữ liệu cơ bản U8, U16,
U32, S8, S16, S32. Chúng đại diện lần lượt cho dữ liệu số nguyên không dấu 8,
16 và 32 bit và số nguyên có dấu 8, 16, 32 bit. Mọi số nguyên dạng nhiều byte
(không tính giá trị điểm ảnh) đều theo thứ tự lớn trước nhỏ sau (bit càng ở đầu
càng có giá trị).
Kiểu dữ liệu PIXEL được xây dựng hiển thị gía trị điểm ảnh của các byte
dạng byte cho mỗi điểm ảnh (bytePerPixel), trong đó 8x bytePerPixel là số bit
mỗi điểm ảnh (bits-per-pixel) thỏa thuận bởi client và server hoặc trong thông
điệp Khởi tạo bên Server hay thông điệp Đặt Định dạng Điểm ảnh
4.1.6.1 Các thông điệp bắt tay khởi tạo
4.1.6.1.1 ProtocolVersion
Quá trình bắt tay bắt đầu khi server gởi cho client thông điệp
ProtocolVersion. Thông điệp này báo cho client biết số phiên bản nghi thức RFB
cao nhất mà server hỗ trợ. Client sau đó sẽ hồi đáp với một thông điệp tương tự cho
biết số phiên bản nghi thức sẽ dùng (có thể khác với số server đưa). Client không
bao giờ yêu cầu phiên bản nghi thức cao hơn số server nêu. Cả server và client đều
có thể hỗ trợ tương thích ngược bằng cơ chế này.
143
Chỉ những phiên bản nghi thức được phát hành lúc này là 3.3, 3.7 và 3.8
(phiên bản 3.5 thường được hồi trả sai bởi một số client, nhưng thường được server
hiểu là 3.3). Việc thêm các dạng mã hóa và mã hóa giả mới thường không có đòi
hỏi thay đổi trong phiên bản nghi thức, vì server chỉ cần đơn giản bỏ qua dạng mã
hóa nếu nó không hiểu.
Thông điệp ProtocolVersion bao gồm 12 byte là một chuỗi ASCII trong định
dạng “RFB xxx.yyy\n” với xxx và yyy là số phiên bản nghi thức chính và phụ, độn
thêm các số 0.
"RFB 003.003\n" (hex 52 46 42 20 30 30 33 2e 30 30 33 0a)
Số byte Giá trị
12
hay
"RFB 003.007\n" (hex 52 46 42 20 30 30 33 2e 30 30 37 0a)
Số byte Giá trị
12
hay
"RFB 003.008\n" (hex 52 46 42 20 30 30 33 2e 30 30 38 0a)
Số byte Giá trị
12
4.1.6.1.2 Bảo mật
Một khi phiên bản nghi thức thỏa thuận xong, server và client phải thỏa
thuận tiếp dạng bảo mật dùng trong kết nối.
Phiên bản 3.7 tiếp Server lập danh sách các dạng bảo mật nó hỗ trợ:
Số byte Type [Giá Mô tả
trị]
Số các dạng bảo mật U8 1
số các dạng bảo mật Mảng U8 Các dạng bảo mật
Nếu server đưa danh sách có ít nhất một dạng được client hỗ trợ, client gởi
trả một byte đơn cho biết dạng bảo mật nào được dùng khi kết nối :
Số byte Type [Giá Mô tả
trị]
144
1 U8 Dạng bảo mật
Nếu số dạng bảo mật bằng 0, sau đó vì một lý do nào đó kết nối thất bại (e.g
server không thể hỗ trợ phiên bản được yêu cầu). Việc này sẽ tạo ra một chuỗi mô
tả lý do (với số độ dài cho biết chuỗi kèm sau dài bao nhiêu).
Số byte Type [Giá Mô tả
trị]
4 Độ dài chuỗi lý do U32
Độ dài chuỗi Mảng U8 Chuỗi lý do
Server đóng kết nối sau khi gởi chuỗi lý do.
Phiên bản 3.3 tíếp Server quyết định dạng bảo mật và gởi một word đơn:
Số byte Type [Giá Mô tả
trị]
4 Dạng bảo mật U32
Dạng bảo mật chỉ có các giá trị 0, 1 và 2.Giá trị 0 cho biết kết nối thất bại và
gởi kèm theo chuỗi lý do đã được mô tả ở trên.
Dạng bảo mật định nghĩa trong tài liệu này là
Số Tên
0 Thất bại
1 Không có gì
2 Chứng thực VNC
Những dạng bảo mật khác là:
Số Tên
5 RA 2
6 RA 2ne
16 Tight
17 Ultra
18 TLS
145
Một khi dạng bảo mật được quyết định, dữ liệu phù hợp với dạng đó sẽ gởi
kèm (xem 4.3.6.2 để biết thêm chi tiết). Vào cuối pha bắt tay bảo mật, nghi thức
thường được tiếp tục với thông điệp SecurityResult.
Chú ý rằng sau pha bắt tay bảo mật, dữ liệu nghi thức tiếp sẽ được gởi trên
một kênh mã hóa hay đã được thay đổi.
4.1.6.1.3 SecurityResult
Server gởi một word (cid:31)ể thông báo client quá trình bắt tay bảo mật (cid:31)ã thành
công hay chưa.
Số byte Type [Giá Mô tả
trị]
Trạng thái: 4 U32
0 OK
1 thất bại
Nếu thành công, nghi thức tiếp tục với thông điệp ClientInitialisation.
Phiên bản 3.8 tiếp Nếu không thành công, server gởi chuỗi mô tả lý do thất bại, và
sau đó đóng kết nối:
Số byte Type [Giá Mô tả
trị]
4 Độ dài chuỗi lý do U32
Độ dài chuỗi Mảng U8 Chuỗi lý do
Phiên bản 3.3 và 3.7 Nếu không thành công, server đóng kết nối.
4.1.6.1.4 ClientInitialisation
Khi client và server đã vui vẻ sẵn sàng nói chuyện với nhau theo dạng bảo
mật đã thỏa thuận, client gởi một thông điệp khởi tạo:
Số byte Type [Giá Mô tả
trị]
1 U8 cờ chia sẻ
146
Cờ chia sẻ khác 0 nếu server thử cho chia sẻ desktop cho các client khác kết
nối, 0 nếu nó thiết lập một kết nối loại trừ cho client này bằng cách ngắt kết nối
những client khác.
4.1.6.1.5 ServerInitialisation
Sau khi nhận thông điệp ClientInitialisation, server gởi thông điệp
ServerInitialisation. Thông điệp này cho client biết bề dài và bề rộng của vùng đệm
khung, định dạng điểm ảnh và tên của desktop:
Số byte Type [Giá trị] Mô tả
chiều rộng của khung U16 2
chiều dài của khung U16 2
định dạng điểm ảnh PIXEL_FORMAT 16
chiều dài tên U32 4
chuỗi tên mảng U8 chiều dài tên
với PIXEL_FORMAT là
Số byte Type [Giá Mô tả
trị]
số bit mỗi điểm ảnh U8 1
độ sâu màu U8 1
cờ big-endian U8 1
cờ true-color U8 1
red-max U16 2
green-max U16 2
blue-max U16 2
red-shift U8 1
green-shift U8 1
blue-shift U8 1
độn 3
147
Định dạng điểm ảnh bên server là số bit dùng cho mỗi giá trị điểm ảnh trên
đường truyền. Giá trị này phải lớn hơn hay bằng độ sâu màu, là số bit dùng thực
trong giá trị điểm ảnh. Hiện tại số bit điểm ảnh phải là 8, 16 hay 32 – ít hơn 8 bit
màu chưa được hỗ trợ. Cờ big-endian là khác 0 (đúng) nếu những điểm ảnh đa byte
được hiểu theo một big-endian (tức là một số có byte chứa giá trị càng lớn thì càng
ở cuối các byte). Hiển nhiên cờ này vô nghĩa với điểm ảnh 8 bit màu.
Nếu cờ true-color là khác 0 (đúng) nếu sáu thành phần cuối xác định làm thế
nào tách cường độ đỏ, xanh và xanh dương từ giá trị điểm ảnh. Red-max là giá trị đỏ tối đa (=2n – 1 với n là số bit dùng cho màu đỏ). Chú ý giá trị này luôn theo thứ
tự big-endian. Red-shift là số lần cần dời bit để lấy giá trị đỏ trong điểm ảnh cho
đến bit quan trọng nhất. Green-max, green-shift và blue-max, blue-shift tương tự
cho màu xanh lá và xanh dương. Chẳng hạn, để tìm giá trị đỏ (từ 0 đến red-max) từ
một điểm ảnh cho trước, làm như sau:
• Tráo đổi giá trị điểm ảnh dựa theo cờ big-endian (e.g nếu cờ big-endian
là 0 (sai) và thứ tự byte của máy chủ là big endian, tráo đổi).
• Dời bit sang phải theo red-shift.
• AND với red-max (theo thứ tự byte của máy chủ).
Nếu cờ true-color là 0 (sai) thì server sẽ dùng giá trị điểm ảnh mà không trực
tiếp lấy từ cường độ đỏ, xanh lá và xanh dương, nhưng được biểu thị chỉ rõ trong
bản đồ màu. Các mục trong bản đồ màu được server thiết lập dùng thông điệp
SetColourMapEntries (phần 4.3.6.4.2).
4.1.6.2 Các dạng bảo mật
4.1.6.2.1 None
Không cần chứng thực và dữ liệu nghi thức gởi không mã hóa.
Phiên bản 3.8 tiếp Nghi thức tiếp tục với thông điệp SecurityResult.
Phiên bản 3.3 và 3.7 Nghi thức tiếp tục với thông điệp ClientInitialisation.
4.1.6.2.2 Chứng thực VNC
148
Chứng thực VNC được dùng và dữ liệu nghi thức gởi không mã hóa. Server
gởi một giá trị thử 16 byte ngẫu nhiên:
Số byte Type [Giá Mô tả
trị]
U16 thử 16
Client mã hóa giá trị thử với DES, dùng mật mã được người dùng cung cấp
là khóa, và gởi trả hồi đáp 16 byte:
Số byte Type [Giá Mô tả
trị]
U16 hồi đáp 16
Nghi thức tiếp tục với thông điệp SecurityResult.
4.1.6.3 Các thông điệp gởi từ client tới server
4.1.6.3.1 SetPixelFormat
Thiết lập định dạng mà giá trị điểm ảnh sẽ gởi trong những thông điệp
FramebufferUpdate. Nếu client không gởi một thông điệp thì server gởi những giá
trị điểm ảnh trong định dạng mặc nhiên ghi rõ trong thông điệp ServerInitialisation.
(phần 4.3.6.1.5).
Nếu cờ true-color là 0 (sai) thì nó cho bíêt một “bản đồ màu” sẽ được dùng.
Server có thể thiết lập bất cứ mục nào trong bản đồ màu dùng thông điệp
SetColourMapEntries (phần 4.3.6.4.2). Ngay tức khắc sau khi client gởi thông điệp
này (SetPixelFormat) bản đồ màu sẽ bỏ trống, thậm chí nếu đã có những mục được
thiết lập bởi server.
Số byte Type [Giá trị] Mô tả
dạng thông điệp U8 0 1
độn 3
định dạng điểm ảnh PIXEL_FORMAT 16
với PIXEL_FORMAT được mô tả trong 4.3.6.15:
149
Số byte Type [Giá Mô tả
trị]
số bit mỗi điểm ảnh U8 1
độ sâu màu U8 1
cờ big-endian U8 1
cờ true-color U8 1
red-max U16 2
green-max U16 2
blue-max U16 2
red-shift U8 1
green-shift U8 1
blue-shift U8 1
độn 3
4.1.6.3.2 FixColourMapEntries
Thông điệp này không còn được dùng. Trước đây nó là một dạng thông điệp.
4.1.6.3.3 SetEncodings
Thiết lập dạng mã hóa mà dữ liệu điểm ảnh dùng được server gởi. Thứ tự
của các dạng mã hóa được ghi trong thông điệp là chỉ dẫn của client cho biết ý
muốn của nó( mã hóa được ghi trước nhất là dạng mà nó thích hơn cả). Server có
thể hoặc không nghe theo chỉ dẫn này. Dữ liệu điểm ảnh có thể luôn luôn gởi dưới
dạng mã hóa thô (raw) thậm chí khi không có khai báo tường minh.
Thêm vào các mã hóa thật, client có thể yêu cầu các “mã hóa giả’ để khai
báo với server rằng nó hỗ trợ các mở rộng nào đó cho nghi thức. Server mà không
hỗ trợ phần mở rộng sẽ đơn giản bỏ qua mã hóa giả. Chú ý rằng client phải ngầm
định server không hỗ trợ phần mở rộng cho đến khi nó nhận thông tin xác nhận rõ
phần mở rộng từ server.
Xem phần 4.3.6.5 cho định dạng dữ liệu cho mỗi mã hóa và phần 4.3.6.6 cho
định nghĩa các mã hóa giả.
150
Số byte Type [Giá Mô tả
trị]
dạng thông điệp U8 2 1
độn 1
số lượng các mã hóa U16 2
theo sau là các số lượng các mã hóa gởi lặp đi lặp lại :
Số byte Type [Giá Mô tả
trị]
dạng mã hóa U32 4
mã hóa thô (raw) 0
mã hóa CopyRect 1
mã hóa RRE 2
mã hóa CoRRE 4
mã hóa Hextile 5
mã hóa ZRLE 16
mã hóa giả Cursor 0xffffff11
mã hóa giả DesktopSize 0xffffff21
Những mã hóa được đăng kí
khác 6,7,8
zlib, tight, zlibhex 0xffffff00 tới 0xffffff10
0xffffff12 tới 0xffffff20
0xffffff22 tới 0xffffffff
các tùy chọn của tight
4.1.6.3.4 FrameBufferUpdateRequest
Báo cho server biết client quan tâm đến một khu vực trong vùng đệm khung
xác định bằng x-position, y-position, width và height. Server thường hồi đáp
FrameBufferUpdateRequest bằng cách gởi một FramebufferUpdate. Chú ý rằng tuy
151
là như thế một FramebufferUpdate có thể gởi để hồi đáp nhiều
FramebuferUpdateRequest.
Server ngầm định rằng client giữ một bản sao của mọt phần trong vùng đệm
khung mà nó quan tâm. Điều này có nghĩa là server thông thường chỉ cần gởi các
cập nhật tăng dần cho client.
Tuy thế, nếu vì vài nguyên nhân nào đó client đã mất nội dung khu vực nó
cần, thì client có thể gởi một FramebufferUpdateRequest với incremental đặt bằng
0 (sai). Việc này yêu cầu server gởi cả nội dung của cả khu vực càng sớm càng tốt.
Khu vực sẽ không cập nhật khi dùng mã hóa CopyRect.
Nếu client đã không mất nội dung khu vực nó quan tâm, thì nó sẽ gởi một
FramebufferRequest với incremental đặt khác 0 (đúng). Nếu và khi có bất kì sự
thay đổi tới khu vực xác định của vùng đệm khung, server sẽ gởi một
FramebufferUpdate. Chú ý rằng có một chu kỳ bất giữa việc gởi và nhận các
FramebufferUpdateRequest và FramebufferUpdate.
Trong trường hợp là một client nhanh (cấu hình mạnh), client có thể muốn
điều chỉnh tần suất gởi các FramebufferUpdateRequest tăng dần để tránh lấn chiếm
đường mạng.
Số byte Type [Giá Mô tả
trị]
dạng thông điệp U8 1
incremental U8 1
x-position U16 2
y-position U16 2
width U16 2
height U16 2
4.1.6.3.5 Sự kiện phím
152
là khi một phím nhấn hoặc thả. Cờ down là khác 0 (đúng) nếu phím đang
được nhấn, 0 (sai) nếu phím đang thả. Phím tự nó cũng được dùng để xác định giá
trị “keysym” định nghĩa bởi Hệ thống X Windows.
Số byte Type [Giá Mô tả
trị]
dạng thông điệp U8 4 1
cờ down U8 1
độn 2
phím U32 4
Dành cho hầu hết các phím, “keysym” giống với giá trị ASCII tương ứng.
Để biết chi tiết, xem The Xlib Reference Manual, phát hành bởi O’Reilly &
Associates, hay xem file tiêu đề
hống X Windows. Một số phím thông dụng khác:
153
Giá trị keysym Tên phím
0xff08 BackSpace
0xff09 Tab
0xff0d Return hay Enter
0xff1b Escape
0xff63 Insert
0xffff Delete
0xff50 Home
0xff57 End
0xff55 Page Up
0xff56 Page Down
0xff51 Left
0xff52 Up
0xff53 Right
0xff54 Down
Tên phím Giá trị keysym
0xffbe F1
0xffbf F2
0xffc0 F3
0xffc1 F4
… …
0xffc9 F12
0xffe1 Shift (trái)
0xffe2 Shift (phải)
0xffe3 Control (trái)
0xffe4 Control (phải)
0xffe7 Meta (trái)
0xffe8 Meta (phải)
0xffe9 Alt (trái)
0xffea Alt (phải)
154
Việc thông dịch keysym khá phức tạp. Nhằm để hoạt độn phối hợp rộng rãi
càng nhiều càng tốt, cần tuân theo các chỉ dẫn sau:
• “Shift state” (i.e. khi các phím shift được nhấn) chỉ nên dùng như một hướng
dẫn khi biên dịch một keysym. Chẳng hạn, trên một bàng phím US ký tự ‘#’
được nhấn kèm theo shift mới được, còn bàn phím UK thì không. Một server
với một bàn phím US nhận một ký tự ‘#’ từ một client với một bàn phím UK
sẽ không được gởi với bất kỳ phím shift nhấn nào cả. Trong trường hợp đó,
server có thể cần “giả” nhấn shift trên hệ thống cục bộ của nó, nhằm để lấy
ký tự có hay không shift, ví dụ, một ký tự ‘3’.
• Việc phân biệt ký tự chữ hoa chữ thường là rất quan trọng. Điều này không
đúng với một số bàn phím trong các Hệ thống X Windows xử lý giống nhau
với cả chữ hoa chữ thường. Chẳng hạn, server nhận được một keysym ‘A’
hoa mà không kèm theo nhấn shift thì nên thông dịch là một ký tự ‘A’ hoa.
Một lần nữa, điều này cũng có thể cần làm “giả” cục bộ nhấn shift.
• Server nên bỏ qua việc “khóa” các keysym chẳng hạn CapsLock và
NumLock khi có thể. Thay vào đó chúng nên được thông dịch mỗi keysym
dựa vào ký tự tùy theo trường hợp của nó.
• Không giống Shift, trạng thái của các phím tinh chỉnh như Control và Alt
cần phải lấy để chỉnh sửa việc thông dịch các keysym khác. Chú ý rằng sẽ
không có những keysym cho ký tự điều khiển ASCII ví dụ như ctrl-a – các
tổ hợp phím này được phát sinh qua khung nhìn bằng cách gởi một nhấn
Control và một nhấn ‘a’.
• Trên khung nhìn khi các phím tinh chỉnh như Control và Alt có thể cũng
được dùng để phát sinh các keysym dựa trên ký tự, các khung nhìn có thể
cần gởi thêm các sự kiện “thả” nhằm để keysym được thông dịch chính xác.
Chẳng hạn, trên một bàn phím PC Đức, ctrl-alt-q sẽ tạo ra ký tự ‘@’. Trong
trường hợp này, khung nhìn cần gởi các sự kiện thả “giả” cho Control và Alt
155
nhằm để ký tự ‘@’ thông dịch đúng (ctrl-alt-q có thể có nghĩa gì đó hoàn
toàn khác đối với server).
• Không có chuẩn chung cho “tab lùi” trong Hệ thống X Windows. Trên một
số hệ thống shift-tab cho keysym “ISO_Left_Tab”, trên số khác nó cho ra
keysym “BackTab” dùng riêng và trên số còn lại nó cho “Tab” và các ứng
dụng lấy từ tình trạng phím shift để biết nó là tab lùi hay tab tiến. Trong nghi
thức RFB cách tiếp cận sau được ưa chuộng hơn. Khung có thể phát sinh
một Tab kèm shift nhấn hơn là một ISO_Left_Tab. Tuy thế, để tương thích
với một số khung nhìn có sẵn, server cần nhận ra ISO_Left_Tab như là một
Tab kèm shift nhấn.
4.1.6.3.6 Sự kiện trỏ
cho biết con trỏ có di chuyển hoặc nút trỏ được nhấn hoặc thả. Con trỏ đang ở vị
trí (x-position, y-position), và trạng thái của các nút 1 đến 8 tính theo thứ tự từ bit 0 đến
7 của button-mask, giá trị bit 0 là thả, giá trị bit 1 là nhấn
Trên một mouse chuẩn, các nút 1, 2 và 3 tương ứng cho các nút trái, giữa và
phải trên mouse. Trên mouse có wheel (bộ phận scroll), mỗi bước quay wheel lên
tương ứng với việc nhấn và thả nút 4, và mỗi bước quay wheel xuống tương úng với
việc nhấn và thả nút 5.
Số byte
Type [Giá trị] Mô tả
dạng thông điệp
U8 5
1
button-mask
U8
1
x-position
U16
2
y-position
U16
2
4.1.6.3.7 ClientCutText
156
Client có dạng văn bản mới ISO 8859-1 (Latin-1) trong vùng cắt văn bản của
nó. Hết mỗi dòng biểu thị bởi ký tự đơn linefeed / newline (sang dòng mới, giá trị 10),
không cần giá trị carriage-return (trở về đầu dòng, giá trị 13). Hiện tại chưa có cách
chuyển đổi văn bản ngoài bộ ký tự Latin-1.
Số byte
Type [Giá trị] Mô tả
1
U8 6
dạng thông điệp
3
độn
4
U32
độ dài chuỗi
Độ dài chuỗi
mảng U8
văn bản
4.1.6.4 Các thông điệp từ server đến client
4.1.6.4.1 FramebufferUpdate
Một cập nhật vùng đệm khung gồm một tuần tự các chữ nhật dữ liệu điểm ảnh
client phải vẽ lên vùng đệm khung của nó. Thông điệp được gởi hồi đáp cho một
FramebufferUpdateRequest từ client. Chú ý rằng có một quá trình bất tận việc gởi và
nhận các FramebufferUpdateRequest và FramebufferUpdate.
Số byte
Type [Giá trị] Mô tả
U8 0
dạng thông điệp
1
độn
1
U16
số các chữ nhật
2
157
đi kèm theo là số các chữ nhật dữ liệu điểm ảnh. Mỗi hình chữ nhật bao gồm:
Số byte
Type [Giá trị] Mô tả
2
U16
x-position
2
U16
y-position
2
U16
width
2
U16
height
4
U32
dạng mã hóa
0
mã hóa thô (raw)
1
mã hóa CopyRect
2
mã hóa RRE
4
mã hóa CoRRE
5
mã hóa Hexile
16
mã hóa ZRLE
0xffffff11
mã hóa giả Cursor
0xffffff21
mã hóa giả DesktopSize
Các mã hóa khác
6, 7, 8
zlib, tight, zlibhex
0xffffff00
đến
0xffffff10
0xffffff12
đến
các tùy chọn của tight
0xffffff20
0xffffff22
đến
0xffffffff
158
tiếp theo là các dữ liệu điểm ảnh trong dạng mã hóa đã xác định. Xem
phần 4.3.6.5 cho định dạng dữ liệu cho mỗi mã hóa và xem phần 4.3.6.6 cho định
nghĩa của mã hóa giả.
4.1.6.4.2 SetColourMapEntries
Khi định dạng điểm ảnh dùng “bản đồ ảnh”, thông điệp này báo cho client biết
những giá trị điểm ảnh xác định trước cần ánh xạ vào các cường độ RGB.
Số byte
Type [Giá trị] Mô tả
1
U8 1
dạng thông điệp
1
độn
2
U16
màu đầu tiên
2
U16
số lượng màu
tiếp theo là lặp đi lặp lại số lượng màu các dữ liệu như sau
Số byte
Type [Giá trị] Mô tả
đỏ
U16
2
xanh lá
U16
2
xanh dương
U16
2
4.1.6.4.3 Bell
Bật loa chuông nếu client có.
Số byte
Type [Giá trị] Mô tả
1
U8 2
dạng thông điệp
4.1.6.4.4 ServerCutText
Client có dạng văn bản mới ISO 8859-1 (Latin-1) trong vùng cắt văn bản của
nó. Hết mỗi dòng biểu thị bởi ký tự đơn linefeed / newline (sang dòng mới, giá trị 10),
159
không cần giá trị carriage-return (trở về đầu dòng, giá trị 13). Hiện tại chưa có cách
chuyển đổi văn bản ngoài bộ ký tự Latin-1.
Số byte
Type [Giá trị] Mô tả
1
U8 6
dạng thông điệp
3
độn
4
U32
độ dài chuỗi
Độ dài chuỗi
mảng U8
văn bản
4.1.6.5 Các mã hóa
4.1.6.5.1 Mã hóa thô
Mã hóa đơn giản nhất là dữ liệu điểm ảnh thô. Trong trường hợp này, dữ liệu
chứa width x height các giá trị điểm ảnh (với width và height là chiều dài và chiều rộng
của hình chữ nhật). Các giá trị chỉ đơn giản biểu thị các điểm ảnh theo thứ tự đường
quét từ trái sang phải. Mọi client RFB đều phải bắt buộc hiểu dữ liệu điểm ảnh dưới
dạng mã hóa thô, và các server chỉ gởi dạng mã hóa thô nếu client không chỉ rõ dạng
mã hóa.
Số byte
Type [Giá
Mô tả
trị]
width x height x bytesPerPixel mảng PIXEL
các điểm ảnh
4.1.6.5.2 Mã hóa CopyRect
Mã hóa CopyRect (sao chép hình chữ nhật) là dạng mã hóa rất đơn giản và hiệu
quả được dùng khi client đã có sẵn dữ liệu điểm ảnh như thế trong vùng đệm khung
của nó. Mã hóa trên đường truyền chỉ đơn giản gồm 2 tọa độ X, Y. Hai tọa độ này cho
biết vị trí trong vùng đệm khung mà client sẽ sao chép hình chữ nhật dữ liệu điểm ảnh
vào. Điều này được ứng dụng trong nhiều tình huống, hiển nhiên nhất là việc người
160
dùng dời một cửa sổ trên màn hình, và khi nội dung của cửa sổ bị cuộn. Một ứng dụng
ít thấy hơn là tích gợp việc việc vẽ văn bản hay lặp lại các mẫu. Một server thông minh
sẽ có thể gởi tường minh một mẫu chỉ một lần, và biết vị trí trước đó của mẫu trong
vùng đệm khung, gởi từ từ các xuất hiện của mẫu sử dụng mã hóa CopyRect.
Số byte
Type [Giá
Mô tả
trị]
2
U16
src-x-position
2
U16
src-y-position
4.1.6.5.3 Mã hóa RRE
RRE viết tắt của rise- and-run-length encoding (mã hóa chiều dài tăng trưởng
và chạy) và như tên ngầm định của nó, mã hóa cần một mã hóa chiều dài chạy (thay
đổi) tương tự hai chiều. Các hình chữ nhật mã hóa RRE đến client trong dạng mà có
thể dựng hình ngay lập tức và hiệu quả bởi các engine đồ họa đơn giản nhất. RRE
không thích hợp với các máy desktop phức tạp, nhưng có thể hữu dụng trong một số
trường hợp.
Ý tưởng căn bản đằng sau RRE là phân vùng một hình chữ nhật dữ liệu điểm
ảnh thành các vùng hình chữ nhật con (các hình chữ nhật phụ), mỗi cái trong chúng
chứa các điểm ảnh của một giá trị đơn và hợp của những cái tạo thành vùng hình chữ
nhật ban đầu. Việc phân vùng gần như tối ưu của một hình chữ nhật cho trước thành
các hình chữ nhật con thì khá dễ tính.
Mã hóa bao gồm một giá trị điểm ảnh nền, Vb (đặc trưng cho hầu hết giá trị
điểm ảnh trong hình chữ nhật) và một biến đếm N, kèm theo một danh sách N các hình
chữ nhật, mỗi cái chứa một tuple
là vị trí tọa độ của hình chữ nhật con tương ứng với góc trên trái của hình chữ nhật, và
(w, h) là chiều rộng và dai của hình chữ nhật con. Client có thể dựng hình chữ nhật ban
161
đầu bằng cách vẽ một hình chữ nhật tô bằng gía trị điểm ảnh nền và sau đó vẽ hình chữ
nhật tô dựa theo các hình chữ nhật con.
Trên đường truyền, dữ liệu được bắt đầu với tiêu đề:
Số byte
Type [Giá
Mô tả
trị]
4
U16
số lượng hình chữ nhật con
PIXEL
số byte mỗi điểm ảnh
giá trị điểm ảnh nền
Đi kèm là số lượng hình chữ nhật con các instance (hiển thị) của cấu trúc:
Số byte
Type [Giá trị] Mô tả
PIXEL
số byte mỗi điểm ảnh
giá trị điểm ảnh hình chữ nhật
2
U16
con
2
U16
x-position
2
U16
y-position
2
U16
width
height
4.1.6.5.4 Mã hóa CoRRE
Chú thích: mã hóa CoRRE đã bị bỏ - Hextile là mã hóa tốt hơn dùng cùng ý
tưởng.
CoRRE (Compact RRE) là một biến thể của RRE, với việc chúng ta sẽ bảo đảm
hình chữ nhật lớn nhất được gởi không quá 255x255 điểm ảnh. Một server muốn
gởi một điểm ảnh lớn hơn thế chỉ đơn giản là cắt nhỏ ra và gởi các hình chữ nhật
RFB nhỏ hơn. Trong mỗi hình chữ nhật nhỏ hơn đó, một byte đơn sẽ biểu thị các
chiều của hình chữ nhật con. Với một desktop đặc trưng, điều này cho nén tốt hơn
cho RRE. Thực tế, việc nén tốt nhất đạt được khi chúng ta giới hạn hơn nữa kích
162
thước hình chữ nhật – cài đặt hiện tại đang dùng tối đa 48x48. Điều này có được là
bởi vì các hình chữ nhật không được mã hóa tốt (tiêu biểu là những cái chứa dữ liệu
hình ảnh) được gởi dạng thô, trong khi những cái khác mã hóa tốt gởi theo CoRRE.
Kícht thước tối đa hình chữ nhật càng nhỏ, việc mã hóa càng tốt (ít hình chữ nhật
thô hơn). Với RRE, cả hình chữ nhật gốc một là gởi theo RRE, hai là gởi theo thô.
Tuy nhiên, vì có một số lượng nhất định hao phí gánh chịu từ mỗi hình chữ nhật
RFB, làm cho kích thước tối đa hình chữ nhật quá nhỏ (và từ đó làm tăng số lượng
hình chữ nhật RFB), dẫn đến việc nén kém hiệu quả hơn.
Dữ liệu bắt đầu bằng tiêu đề:
Số byte
Type [Giá
Mô tả
trị]
4
U16
số lượng hình chữ nhật con
PIXEL
số byte mỗi điểm ảnh
giá trị điểm ảnh nền
Đi kèm là số lượng hình chữ nhật con các instance (hiển thị) của cấu trúc:
Số byte
Type [Giá trị] Mô tả
PIXEL
giá trị điểm ảnh hình chữ nhật
số byte mỗi điểm ảnh
2
U16
con
2
U16
x-position
2
U16
y-position
2
U16
width
height
4.1.6.5.5 Mã hóa Hextile
Hextile là một biến đổi của ý tưởng CoRRE. Các hình chữ nhật được cắt ra các
tile (lát) 16x16, cho phép các chiều hình chữ nhật xác định bằng mỗi 4 bit, tổng cộng
16 bit. Không giống CoRRE, các lát không phải là các hình chữ nhật RFB cơ bản nhất.
163
Khi cắt một hình chữ nhật gốc thành các lát, điều này thực hiện theo tính tóan trước.
Điều này có nghĩa là vị trí và kích thước của mỗi lát không cần phải xác định tường
minh – nội dung mã hóa của các lát chỉ đơn giản theo một lát khác trong thứ tự tính
toán trước. Sắp xếp thứ tự các lát chúng ta dùng thì phải bắt đầu từ góc trái trên đi theo
từ trái qua phải, từ trên xuống dưới. Nếu độ rộng của hình chữ nhật không chính xác là
bội số của 16 thì độ rộng của lát cuối trên mỗi dòng sẽ nhỏ lại tương ứng.Tương tự nếu
độ dài của hình chữ nhật không chính xác là bội số của 16 thì độ dài của mỗi lát trên
dòng cuối sẽ nhỏ lại tương ứng.
Mỗi lát mã hóa hoặc thô hoặc là biến thể RRE. Mỗi lát có một giá trị điểm ảnh
nền, như đề cập ở trên. Tuy nhiên, giá trị nền không cần xác định tường minh cho một
lát cho trước nếu nó giống với nền của lát trước đó. Nếu mọi hình chữ nhật con của
một lát có cùng giá trị điểm ảnh, giá trị này có thể xác định đúng một lần thành giá trị
điểm ảnh mặt tiền cho cả lát. Cũng như nền, giá trị điểm ảnh mặt tiền có thể để trống,
ngụ ý nó đã có trong lát trước rồi.
Do vậy, dữ liệu mỗi lát mã hóa theo thứ tự. Mỗi lát bắt đầu bằng byte dạng
subencoding (mã hóa phụ), mang ý nghĩa mặt nạ áp cho số bit:
Số byte
Type [Giá trị] Mô tả
1
U8
subencoding-mask
1
Thô (raw)
2
BackgroundSpecified
4
ForegroundSpecified
6
AnySubrects
16
SubrectsColoured
Nếu bit Raw được đặt lên thì các bit còn lại không liên quan; width x height giá
trị điểm ảnh tiếp theo (với widht và height là độ rộng và dai của lát). Nếu không các bit
còn lại trong mặt nạ phải như sau:
164
BackgroundSpecified – nếu đặt, một giá trị điểm ảnh theo sau sẽ xác định màu nền
cho lát này:
Số byte
Type [Giá trị] Mô tả
PIXEL
số byte mỗi điểm ảnh
giá trị điểm ảnh nền
Lát đầu tiên trong một hình chữ nhật phải có bt đặt lên. Nếu bit này không đặt
thì nền sẽ giống với lát cuối.
ForegroundSpecified – nếu đặt, giá trị điểm ảnh theo sau sẽ xác định giá trị màu mặt
tiền được dùng cho mọi hình chữ nhật con của lát này:
Số byte
Type [Giá trị] Mô tả
PIXEL
số byte mỗi điểm ảnh
giá trị điểm ảnh mặt tiền
Nếu bit này được thì bit SubrectsColoured phải là 0.
AnySubrects – nếu đặt, một byte đơn theo sau cho biết số lượng các hình chữ nhật con:
Type [Giá trị] Mô tả
Số byte
U8
1
số lượng hình chữ nhật
Nếu không đặt, không có hình chữ nhật con (i.e. cả lát chỉ là một màu nền trơ).
SubrectsColoured – nếu đặt thì mỗi hình chữ nhật con sẽ đi kèm giá trị điểm ảnh cho
biết màu của hình chữ nhật con, vậy một hình chữ nhật con gồm:
Số byte
Type [Giá trị] Mô tả
PIXEL
giá trị điểm ảnh hình chữ nhật
số byte mỗi điểm ảnh
U8
1
con
U8
1
x-and-y-position
165
width-and-height
Nếu không đặt, mọi hình chữ nhật con có cùng màu, màu mặt tiền; nếu bit
ForegroundSpecified không được đặt thì mặt tiền sẽ giống với lát cuối. Một hình chữ
nhật con là:
Số byte
Type [Giá trị] Mô tả
U8
1
x-and-y-position
U8
1
width-and-height
Vị trí và kích thước của mỗi hình chữ nhật con xác định trong hai byte,
x-and-y-position và width-and-height. Bốn bit quan trọng nhất của x-and-y-position
xác định vị trí X, bốn bít còn lại xác định vị trí Y. Bốn bit quan trọng nhất của width-
and-height xác định độ rộng trừ đi một, bốn bít còn lại xác định độ dài trừ đi một.
4.1.6.5.6 Mã hóa ZRLE
ZRLE viết tắt cho Zlib Run-Length Enconding, là kết hợp của khả năng nén
theo zlib, cắt lát, phân bảng màu và mã hóa chiều dài chạy. Trên đường truyền, hình
chữ nhật bắt đầu với một trường rộng 4 byte, và theo sau là những byte dữ liệu nén
theo zlib. Một đối tượng “theo dòng” zlib đơn được dùng cho một kết nối RFB cho
trước, để các hình chữ nhật ZRLE phải được mã hóa và giải mã nghiêm ngặc theo thứ
tự.
Số byte
Type [Giá trị] Mô tả
4
U32
chiều dài
mảng U8
zlibData (dữ liệu zlib)
chiều dài
166
zlibData khi được bung nén hiển thị bằng các lát 64x64 điểm ảnh theo thứ tự
trái qua phải, trên xuống dưới, tương tự như hextile. Nếu độ rộng của hình chữ nhật
không chính xác là bội số của 64 thì độ rộng của lát cuối trên mỗi dòng sẽ nhỏ lại
tương ứng.Tương tự nếu độ dài của hình chữ nhật không chính xác là bội số của 64 thì
độ dài của mỗi lát trên dòng cuối sẽ nhỏ lại tương ứng.
ZRLE sử dụng kiểu dữ liệu mới CPIXEL (compressed pixel – điểm ảnh nén).
Kiểu này cũng giống như PIXEL cho định dạng điểm ảnh đã xác định trước, ngoại trừ
cờ
true-colour là khác 0, số bit mỗi điểm ảnh là 32, độ sâu là 24 hay thấp hơn và mọi bit
tạo cường độ đỏ, xanh lá, xanh dương gắn vừa vào 3 byte thứ yếu nhất hoặc 3 byte
quan trọng nhất Trong trường hợp này, một CPIXEL chỉ dài độ 3 byte, và chứa 3 byte
thứ yếu nhất hay 3 byte quan trọng nhất, tùy bên nào phù hợp hơn. bytePerCPixel là số
byte trong CPIXEL.
Mỗi lát bắt đầu bằng một byte dạng subendcoding. Bit cao nhất của byte này đặt
lên nếu lát được mã hóa chiều dài chạy, nếu không sẽ xóa. Bảy bit dưới cho biết kích
thước của bảng màu dùng – 0 có nghĩa là không có bảng màu, một có nghĩa là lát có
một màu đơn, 2 đến 127 cho biết bảng màu có kích thước như thế. Các giá trị có thể có
của subencoding là:
0 – dữ liệu điểm ảnh thô. width x height giá trị điểm ảnh tiếp theo (với width và height
là độ rộng và độ dài của lát):
Số byte
Type [Giá
Mô tả
trị]
width
x
height
x
mảng CPIXEL
các điểm ảnh
bytesPerCPixel
167
1 – một lát cứng là một lát chỉ có một màu đơn:
Số byte
Type [Giá
Mô tả
trị]
CPIXEL
bytesPerCPixel
pixelValue – giá trị điểm
ảnh
2 to 16 – các dạng bảng màu đóng gói. Theo sau bảng màu, bao gồm các paletteSize
(= subencoding) giá trị điểm ảnh. Sau các điểm ảnh đóng gói, mỗi điểm ảnh được biểu
diễn bằng một trường bit cho biết chỉ mục cho bảng màu (0 có nghĩa là mục đầu tiên
bảng màu ). Cho paletteSize bằng 2, trường 1 bit được dùng, cho paletteSize bằng 3
hay 4, trường 2 bit được dùng, và cho paletteSize từ 5 đến 16, trường 4 bit được dùng.
Các trường bit đóng gói trong các byte, các bit quan trọng nhất biểu diễn các điểm ảnh
cực trái (i.e. big endian). Cho các lát không rộng bằng bội số 8, 4 hay 2 điểm ảnh, các
bit độn sẽ dùng để canh lề mỗi dòng cho chính xác số lượng byte.
Số byte
Type [Giá
Mô tả
trị]
paletteSize x bytesPerCPixel
mảng CPIXEL
bảng màu
mảng U8
m
các điểm ảnh đóng gói
17 đến 127 – không dùng (không có tiến triển trên bảng màu RLE).
128 – RLE trơ, bao gồm số lượng các đường chạy, lặp lại cho đến khi lát gởi hết.
Đường chạy có thể bắt đầu từ cuối một dòng sang bắt đầu dòng kế tiếp. Mỗi đường
chạy được biểu diễn bởi một giá trị điểm ảnh đơn theo sau là chiều dài của đường chạy.
Chiều dài biểu diễn một hoặc nhiều byte. Chiều dài được tính nhiều hơn một so với
tổng các byte cho biết độ dài. Bất kỳ giá trị byte khác 255 đều được xem là byte cuối.
168
Ví dụ, chiều dài 1 biểu diễn [0], 255 là [254], 256 là [255, 0], 257 là [255, 1], 510 là
[255, 254] , 511 là [255, 255, 0] ...
Số byte
Type [Giá
Mô tả
trị]
U8
paletteIndex + 128
1
mảng U8 255
floor((runLength – 1)/255)
U8
(runLength – 1)%255
1
4.1.6.6 Mã hóa giả
4.1.6.6.1 Mã hóa giả Cursor
Một client yêu cầu mã hóa giả Cursor phải khai báo nó có thể vẽ con trỏ mouse
cục bộ được. Điều này có thể làm tăng một cách đáng kể việc trình diễn trên các đường
truyền tốc độ thấp. Server thiết lập hình dạng con trỏ bằng cách gởi một hình chữ nhật
giả với mã hóa giả Cursor là một phần của việc cập nhật. Các tọa độ x-position và y-
position của hình chữ nhật giả cho biết hotspot (đầu trỏ) của con trỏ, và width và height
cho biết độ rộng và dài của con trỏ tính bằng điểm ảnh. Dữ liệu gồm width x height
giá trị điểm ảnh đi kèm là một mặt nạ bit. Mặt nạ bit gồm các dòng quét từ trái sang
phải, từ đỉnh xuống dưới, mỗi dòng quét được độn thêm vào một số các byte tính bằng
floor((width+ 7)/8). Trong mỗi byte, bit quan trọng nhất biểu diễn điểm ảnh cực trái,
với một bit đó mang ý nghĩa điểm ảnh tương ứng trong con trỏ có hiệu lực.
Số byte
Type [Giá
Mô tả
trị]
width x height x bytesPerPixel mảng PIXEL
các điểm ảnh của con trỏ
169
mảng U8
floor((width + 7)/8) * height
mặt nạ bit
4.1.6.6.2 Mã hóa giả DesktopSize
Một client yêu cầu mã hóa giả Cursor phải khai báo nó có thể sao chép với sự
thay đổi trong độ rộng và/ hay độ dài vùng đệm khung. Server thay đổi kích thước
desktop bằng cách gởi một hình chữ nhật giả với mã hóa giả DesktopSize như là hình
chữ nhật cuối cùng của quá trình cập nhật. Các tọa độ x-position và y-position bỏ qua,
và width và height cho biết độ rộng và độ dài của vùng đệm khung mới. Không có dữ
liệu kèm theo với hình chữ nhật giả.
4.2 H323
4.2.1 Chuẩn H323 là gì ?
H.323 là chuẩn của International Telecommunications Union(ITU), cung cấp
những đặc điểm kỹ thuật cho máy tính, thiết bị, và dịch vụ cho việc giao tiếp đa truyền
thông qua mạng mà không cần phải quan tâm đến chất lượng dịch vụ. Các máy tính và
thiết bị có sử dụng H.323 có thể đem đến âm thanh, hình ảnh hay dữ liệu theo thời gian
thực. Chuẩn này dựa trên Internet Engineering Task Force (IETF), Real Time Protocol
(RTP) và Real Time Control Protocol (RTCP), cộng với một số protocol được thêm
vào cho việc thực hiện cuộc gọi, trao đổi dữ liệu và giao tiếp âm thanh, hình ảnh theo
thời gian thực.
Người dùng có thể kết nối với người khác thông qua internet và sử dụng
những loại sản phẩm khác nhau có hỗ trợ H.323. H.323 định nghĩa cách mà thông tin
được định dạng và đóng gói trước khi truyền qua mạng. Mã hóa âm thanh và hình ảnh,
và giải mã đầu vào/ đầu ra từ nguồn âm thanh, hình ảnh cho việc giao tiếp giữa các
điểm. Một codec( bao gồm mã hóa và giải mã) sẽ chuyển đổi tín hiệu âm thanh và hình
ảnh giữa hình thức tương tự và số.
170
H.323 cũng xác định dịch vụ T.120 cho việc trao đổi dữ liệu và hội nghị trong
một phiên của H.323. Quan trọng nhất, T.120 này hỗ trợ việc xử lý dữ liệu chung với
âm thanh và hình ảnh của H.323 hay riêng lẻ.
Microsoft và trên 120 công ty hàng đầu khác đã tuyên bố dự định của họ trong
việc hỗ trợ và áp dụng H.323 trong sản phẩm và dịch vụ của họ. Với sự hỗ trợ rộng lớn
này, H.323 sẽ là một chuẩn cho hội nghị âm thanh, hình ảnh qua Internet.
4.2.2 Những lợi ích của H.323
4.2.2.1
Chuẩn mã hóa
H.323 thiết lập chuẩn cho việc nén và giải nén dòng dữ liệu âm thanh và hình
ảnh, bảo đảm những thiết bị từ những hãng khác nhau có một vài lãnh vực hỗ trợ
chung.
4.2.2.2
Khả năng liên kết hoạt động:
Người dùng muốn dùng hội nghị sẽ không lo lắng giữa các điểm nhận. Ngoài
việc đảm bảo rằng các điểm nhận sẽ giải mã được thông tin, H.323 thiết lập phương
thức cho người dùng ở nơi nhận có thể giao tiếp đúng với người gởi. Chuẩn này cũng
thiết lập cách thiết lập cuộc gọi và những nghi thức điều khiển.
4.2.2.3
Độc lập với mạng:
H.323 được thiết kế để chạy bên trên kiến trúc mạng thông thường. Khi kỹ
thuật mạng phát triển, và khi kỹ thuật quản lý băng thông được củng cố, những giải
pháp dựa trên H.323 sẽ có nhiều tiện ích từ những khả năng được củng cố này.
171
4.2.2.4
Độc lập với nền và ứng dụng:
H.323 không gắn chặt với phần cứng hay ứng dụng nào. Những nền tảng
tương thích H.323 sẽ được dùng trong nhiều kích cỡ và hình dáng, bao gồm máy tính
cá nhân có hỗ trợ video, nền tảng chuyên dụng, thiết bị di động dựa trên IP v.v…
4.2.2.5 Hỗ trợ đa điểm :
Mặc dù H.323 có thể hổ trợ hội nghị với ba hay nhiều điểm mà không đòi hỏi
một thiết bị điều khiển đa điểm. Khả năng này được bao gồm trong các thành phần của
H.323
4.2.2.6 Quản lý băng thông:
Luồng âm thanh và hình ảnh thì tốn băng thông
và có thể làm cản trở sự
hoạt động của mạng. H.323 giải quyết vấn đề này bằng cách cung cấp cách quản lý
băng thông. Nhà quản lý mạng có thể hạn chế số kết nối H.323 đồng thời trong mạng
của họ hay lượng băng thông có giá trị trong ứng dụng dùng H.323. Những điều này
đảm bảo rằng vấn đề về lưu lượng sẽ bị xóa bỏ.
4.2.2.7 Hỗ trợ một nhiều:
Trong hội nghị đa điểm , H.323 hỗ trợ việc truyền dữ liệu một nhiều. Gởi một
nhiều sẽ gởi gói tin 9ến một số đích mà không cần hồi đáp. Truyền theo một nhiều sử
dụng băng thông một cách hiệu quả hơn vì tất cả thiết bọ trên mạng đều đọc trong cùng
một nhóm cùng đọc được từ một luồng dữ liệu
4.2.2.8
Tính linh họat:
Hội nghị sử dụng H.323 có thể sử dụng nhiều điểm cuối với những khả năng
khác nhau. Ví dụ, thiết bị đầu cuối với khả năng chỉ có âm thanh có thể tham gia vào
hội nghị với thiết bị có khả năng âm thanh hay dữ liệu. Hơn nữa thiết bị đa truyền
thông H.323 có thể chia sẻ phần dữ liệu của một hội nghị có hình ảnh với thiết bị chỉ
172
có dữ liệu dựa trên T.120 trong khi chia sẻ tiếng nói, hình ảnh và dữ liệu với các thiết
bị H.323 khác.
4.2.2.9 Hội nghị thông qua mạng
Nhiều người dùng muốn thiết lập hội nghị từ mạng LAN đến mạng ở xa. Ví
dụ, H.323 thiết lập phương tiện để liên kết hệ thống máy vi tính dựa trên mạng LAN
với hê thống dựa trên ISDN. H.323 sử dụng kỹ thuật mã hóa thông dụng từ chuẩn của
hội nghị có hình ảnh để làm giảm độ trễ và cung cấp sự thể hiện tối ưu.
4.2.3 Những chuẩn nào áp dụng đến H.323
4.2.3.1
Tín hiệu gọi và điều khiển:
H.323: hệ thông giao tiếp đa phương tiện dựa trân gói
H.225: chuẩn điều khiển cuộc gọi
H.235: bảo mật
H.245: chuẩn điều khiển phương tiện truyền
Q.931: cung cấp tín hiệu số
H.450.1: chuẩn cho sự hỗ trợ các dịch vụ thêm vào H.323
4.2.3.2 Mã hóa và giải mã âm thanh:
G.711 : Mã hóa và giải mã âm thanh PCM 56/64 kpbs
G.722 : Mã hóa và giải mã âm thanh cho 7Khz ở 48/56/64kbps
G.723.1 : Mã hóa và giải mã tiếng nói cho 5.3 và 6.3 kbps
G.728 : Mã hóa và giải mã tiếng nói cho 16 kbps
G.729 : Mã hóa và giải mã tiếng nói cho 8/16 kbps
4.2.3.3 Mã hóa và giải mã hình ảnh:
H.261: Mã hóa và giải mã hình ảnh >=64kbps
173
H.263: Mã hóa và giải mã hình ảnh <64kbps
4.2.3.4
Những chuẩn có liên quan: H.320 , H.324, T120
4.2.4 Kiến trúc H.323
H.323 định nghĩa bốn thành phần chính yếu cho hệ thống giao tiếp trên mạng:
Terminals, Gateways, Gatekeepers, and Multipoint Control Units
4.2.4.1
Terminals:
Terminals là thiết bị cuối bên người dùng cung cấp sự giao tiếp hai chiều và
theo thời gian thực. Tất cả các terminals phải hỗ trợ giao tiếp âm thanh, hình ảnh và dữ
liệu là tùy chọn.
Tất cả các H.323 terminals hỗ trợ H.245, sử dụng hỗ trợ thương lượng kênh
truyền và khả năng. Ba thành phần khác đòi hỏi phải có là: Q.931 cho báo hiệu và thiết
lập cuộc gọi, RAS (Registration/Admission/Status) để giao tiếp với GatewayKeeper và
RTP/RTPC cho việc quản lý thứ tự các gói tin âm thanh và hình ảnh.
Các thành phần tùy chọn trong H.323 terminals là codec hình ảnh, T.120,
MCU.
4.2.4.2 Gateways:
Là thành phần tùy chọn trong hội nghị dùng H.323. Gateway cung cấp nhiều
dịch vụ. Ví dụ: chức năng chuyển đổi giữa các định dạng truyền dữ liệu (H.225 và
H.242)và các thủ tục giao tiếp (H.245 và H.242). Hơn nữa, Gateway cung có thể
chuyển đổi giữa việc mã hóa âm thanh và hình ảnh và thực hiện các cuộc gọi và kết
thúc cả trên mạng LAN và mạng theo cơ chế chuyển mạch
Nói chung, mục đích của Gateway là phản ánh đặc điểm của thiết bị đầu cuối
LAN và thiết bị đầu cuối SCN và ngược lại. Ứng dụng chính của gateway là :
Thiết lập đường kết nối với thiết bị đầu cuối tín hiệu tương tự PSTN
174
Thiết lập đường kết nối với thiết bị đầu cuối hỗ trợ H.320 từ xa thông qua
mạng chuyển mạch dựa trên ISDN.
Thiết lập đường kết nối với thiết bị đầu cuối hỗ trợ H.324 từ xa thông qua
mạng PSTN.
Gateway không đòi hỏi nếu kết nối với mạng khác không có vì điểm cuối phải
giao tiếp trực tiếp với điểm cuối khác trên cùng mạng LAN. Terminals giao tiếp với
Gateway thông qua chuẩn H.245 và Q.931.
Hình 4-2 Gateway Proticol Stack
4.2.4.3 Gatekeeper:
GateKeeper là thành phần quan trọng nhất trong mạng có sử dụng H.323. Nó
hoạt động như là trung tâm của mọi cuộc gọi trong vùng của nó và cung cấp các dịch
vụ điều khiển cuộc gọi để đăng ký đến điểm cuối. Trong nhiều trường hợp khác nhau
thì thì gatekeeper hoạt động như là một switch ảo.
GateKeeper thực hiện hai chức năng điều khiển cuộc gọi quan trọng. Thứ nhất
là chuyển địa chỉ từ định danh mạng LAN cho thiết bị và gateway sang địa chỉ IP hay
IPX. Thứ hai là quản lý băng thông
175
Tập hợp tất cả Terminals, Gateways, MultiPoint Control Unit quản lý bởi một
GateKeeper duy nhất thì được xem như là một vùng H.323
Một đặc điểm tùy chọn nhưng có giá trị là khả năng tìm đường cho cuộc gọi
H.323. Bằng cách dẫn đường một cuộc gọi thông qua GateKeeper, cuộc gọi có thể
được điều khiển một cách hiệu quả hơn. Những người cung cấp dịch vụ cần khả năng
này để tính tiền cho cuộc gọi thông qua mạng của họ. Dịch vụ này cũng có thể hướng
cuộc gọi đến một điểm cuối khác nếu điểm cuối được gọi không có giá trị. Hơn nữa,
một khả năng của GateKeeper về việc dẫn đường cho cuộc gọi có thể giúp cho việc
quyết định cân băng giữa nhiều gateway.
Trong khi, Gatekeeper về mặt luận lý thì độc lập với điểm cuối H.323, tuy
nhiên nhiều nhà sản xuất tích hợp chức năng Gatekeeper vào trong việc thực thi vật lý
của Gateways và MCU.
Một Gatekeeper không đòi hỏi trong hệ thống H.323. Tuy nhiên nếu có
Gatekeeper, terminal có thể sử dụng các dịch vụ cung cấp bởi Gatekeeper. RAS định
nghĩa gồm chuyển đổi địa chỉ, điều khiển về quyền, điều khiển băng thông, và quản lý
vùng.
Gatekeeper cũng có vai trò trong việc kết nối đa điểm. Để hỗ trợ cho hội nghị
đa điểm, người dùng phải sử dụng một Gatekeeper để nhận kênh điều khiển H.245 từ
hai terminals trong hội nghị điểm nối điểm. Khi dạng hội nghị này chuyển sang đa
điểm, Gatekeeper có thể chuyển hướng kênh điều khiển H.245 sang MC(multiple
Controller). Gatekeeper không xử lý tính hiệu mà chuyển tín hiểu giữa các terminal
hay giữa terminal và MC.
Chức năng bắt buộc của một Gatekeeper
1.Chuyển địa chỉ: Những cuộc gọi bên trong mạng H.323 có thể dùng định
danh để đánh địa chỉ cho các thiết bị đầu cuối. Những cuộc gọi có nguồn gốc bên ngòai
mạng H.323 và nhận bởi gateway có thể sử dụng một số điện thọai E.164 (ví dụ 310-
442-9222) để đánh địa chỉ cho thiết bị đầu cuối. Gatekeeper chuyển số điện thọai
176
E.164 này hay định danh sang địa chỉ mạng. Việc chuyển này sử dụng một bảng được
Update bởi Registration message.
2. Điều khiền quyền: Gatekeeper có thể điều khiển quyền của điểm cuối khi
truy cập vào mang H.323. Nó sử dụng RAS message, ARQ( Admission Request), ACF
(confirm), và Reject(ARJ). Nếu điều khiển quyền không có gì thì mọi yêu cầu đều cho
phép.
3. Điều khiển băng thông:
Hỗ trợ cho yêu cầu băng thông, xác định và từ chối thông điệp. Điều này có
thể dựa vào việc quản lý băng thông. Nếu điều khiển băng thông không có gì thì mọi
yêu cầu đều cho phép.
4.Quản lý vùng: Gatekeeper cung cấp những chức năng trên cho terminal,
MCU, Gateway…đã được đăng ký trong vùng của nó điều khiển
Những chức năng bổ sung Gatekeeper bao gồm:
1. Tín hiệu điều khiển cuộc gọi: Trong hội nghị điểm nối điểm, Gatekeeper có
thể xử lý tín hiệu điều khiển cuộc gọi Q.931. Như một sự lựa chọn, Gatekeeper có thể
gởi tín hiệu Q.931 ở những điểm cuối đến trực tiếp với nhau.
2. Quyền cuộc gọi: Gatekeeper có thể từ chối cuộc gọi từ terminal dựa trên
đặc điểm kỹ thuật của Q.931. Lý do từ chối có thể bao gồm hạn chế truy cập đến hay đi
từ các terminal hay gateway đặc biệt, hạn chế truy cập trong một khoảng thời gian.
Tiêu chuẩn để xác định quyền thành công hay thất bại là ngoài phạm vi của H.323.
3. Quản lý băng thông: Gatekeeper có thể từ chối tất cả các cuộc gọi từ một
terminal nếu nó thấy rằng băng thông tối thiểu không có. Chức năng này cũng hoạt
động trong lúc đang gọi nếu terminal đòi hỏi thêm băng thông. Tiêu chuẩn cho việc
quyết định băng thông có đủ hay không nằm ngoài phạm vi của H.323
4. Quản lý cuộc gọi: Gatekeeper có thể duy trì danh sách các cuộc gọi H.323
đang diễn ra để chỉ ra ràng terminal bận hay cung cấp thông tin cho chức năng quản lý
băng thông.
177
Hình 4-3 Các thành phần của gatekeeper
4.2.4.4 Multipoint Control Unit (MCU)
Multipoint Control Unit (MCU) hỗ trợ hội nghị giữa ba hay nhiều điểm cuối.
Dưới H.323, MCU bao gồm một Multipoint Controller(MC), bắt buộc, và có hay
không Multipoint Processor(MP). MC nắm giữ những cuộc thương lượng H.245 giữa
tất cả các terminals, để xác định khả năng thông dụng nhất cho việc xử lý âm thanh và
hình ảnh. MC cũng điều khiển tài nguyên của hội nghị bằng cách quyết định xem dòng
âm thanh hình ảnh nào sẽ truyền theo dạng multicast.
MC không giải quyết trực tiếp với dòng truyền nào. Đó dành cho MP, nó pha
trộn, chuyển và xử lý âm thanh hình ảnh hay bit dữ liệu. Khả năng MC, MP có thể có
trong các thành phần dành riêng hay một phần của những thành phần H.323 khác.
178
4.2.5 Hội thảo đa điểm:
Khả năng của hội thảo đa điểm có thể được giải quyết bằng được sử dụng
trong nhiều phương pháp và cấu hình khác nhau khi dùng H.323.
4.2.5.1 Hội thảo đa điểm tập trung:
Yêu cầu có sự tồn tại của MCU để làm cho hội thảo đa điểm được dễ dàng.
Tất cả các terminal gởi âm thanh, hình ảnh, dữ liệu và dòng điều khiển đến MCU dưới
dạng điểm nối điểm. MCU tập trung quản lý hội thảo sử dụng chức năng điều khiển
H.245- định nghĩa khả năng của mỗi terminal. MP thực hiện các chức năng xử lý âm
thanh, phân tán dữ liệu, xử lý/chuyển đổi video trong các hội thảo đa điểm và gửi dòng
kết quả lại cho các terminal. MP cũng cung cấp sự chuyển đổi giữa hai loại codec và tỷ
lệ khác nhau, và cũng có thể sử dụng multicast để phân tán hình ảnh video đã được xử
lý. Một MCU đặc thù hỗ trợ hội thảo đa điểm tập trung thường gồm một MC, âm
thanh, hình ảnh, và/hay dữ liệu MP.
4.2.5.2 Hội thảo đa điểm phân tán:
Có thể sử dụng kỹ thuật multicast. Những terminal tham gia vào H.323 sẽ
multicast âm thanh và hình ảnh đến những terminal khác mà không cần gởi dữ liệu đến
một MCU. Chú ý rằng việc điều khiển dữ liệu đa điểm vẫn được xử lý tập trung bởi
MCU, và thông tin kênh điều khiển H.245 vẫn được truyền đến một MC dưới dạng
điểm nối điểm.
Terminal nhận chịu trách nhiệm cho việc xử lý nhiều dòng âm thanh, hình ảnh
đến. Terminal sử dụng kênh điều khiển H.245 để chỉ cho MC có bao nhiêu dòng âm
thanh và hình ảnh cùng lúc có thể giải mã. Số lượng những khả năng cùng lúc của một
terminal không hạn chế số dòng âm thanh hay hình ảnh được multicast trong hội thảo.
MP cũng có thể cung cấp sự chọn lựa hình ảnh hay pha trộn âm thanh trong hội thảo đa
điểm phân tán.
179
4.2.5.3 Hội thảo đa điểm kết hợp:
Sử dụng sự kết hợp của tập trung và phân tán. Tín hiệu H.245 và dòng âm
thanh hay video được xử lý thông qua các thông điệp điểm nối điểm đến MCU. Tín
hiệu còn lại (âm thanh hay video) được truyền tới các terminal H.323 cùng tham gia
bằng multicast.
Một thuận lợi của hội thảo tập trung là tất cả các terminal H.323 đều hỗ trợ
giao tiếp điểm nối điểm. MCU có thể xuất nhiều unicast đến các thành viên hội thảo và
không cần khả năng đặc biệt nào về mạng. Như một sự lựa chọn, MCU có thể nhận
nhiều unicast, trộn âm thanh và chuyển đổi video, xuất một dòng multicast, duy trì
băng thông mạng.
H.323 cũng hỗ trợ hội thảo đa điểm hỗn tạp - một số terminal ở dạng hội thảo
đa điểm tập trung, số khác ở dạng hội thảo đa điểm phân tán, và một MCU cung cấp
cầu nối cho 2 dạng này. Terminal không biết tính chất hỗn tạp của hội thảo, mà chỉ biết
dạng hội thảo mà nó gửi và nhận.
Bằng cách hỗ trợ cả multicast và unicast, H.323 kết nối công nghệ hiện tại và
tương lai. Multicast giúp dùng băng thông mạng hiệu quả hơn , nhưng gây sự tính toán
cho terminal - phải trộn và chuyển đổi các dòng âm thanh/video nhận được. Hơn nữa,
sự hỗ trợ của multicast cần thiết trong các router và switch.
Một MC có thể định vị trong một Gatekeeper, Gateway, Terminal, hay MCU.
Hình 4-4 Ví dụ Hybrid và Decentralized
180
Xét ví dụ đơn giản, một hội thảo đa điểm được thiết lập giữa 3 client (hình
trên ). Một terminal client (Client B) thực hiện chức năng MC. Tất cả terminal đều có
thể dùng multicast để tham gia vào hội thảo phân tán. Chức năng MP trên mỗi nút sẽ
trộn và trình diễn các tính hiệu âm thanh và hình ảnh cho người dùng. Phương pháp
này làm giảm thiểu nhu cầu về tài nguyên mạng. Tuy nhiên, mạng phải được cấu hình
hỗ trợ multicast.
Một MCU riêng có thể được dùng chỉ để xử lý các chức năng audio, dữ liệu và
điều khiển. Trong cấu hình này video vẫn được multicast, nhằm duy trì băng thông.
MCU này có thể là một hệ thống chuyên môn hay một terminal có mã lực mạnh
Hội thảo đa điểm kết nối các terminal trong LAN và không mạng rất có ích
cho các cấu hình mà chức năng MCU được tích hợp chặt chẽ với Gateway.
4.2.6
H.225 Registration, Admission, and Status
4.2.6.1 H.225 tín hiệu gọi :
Tín hiệu gọi H.225 được dùng để thiết lập kết nối giữa các điểm cuối H.323
(terminal và gateway), phục vụ cho vận chuyển dữ liệu thời gian thực. Call signaling
liên quan đến sự trao đổi các thông điệp giao thức H.225 trên một kênh call-signaling.
Ví dụ, các thông điệp giao thức H.225 dùng TCP trong mạng H.323 dựa trên IP.
Các thông điệp H.225 được trao đổi giữa các điểm cuối nếu không có
gatekeeper trong mạng H.323. Khi một gatekeeper tồn tại trong mạng, các thông điệp
H.225 được trao đổi hoặc trực tiếp giữa các endpoint hoặc giữa các endpoint sau khi
được truyền qua gatekeeper. Phương pháp thứ nhất là call signaling trực tiếp. Phương
pháp thứ hai gọi là call signaling truyền qua gatekeeper. Gatekeeper sẽ quyết định
phương pháp nào trong quá trình trao đổi thông điệp về quyền RAS-admission.
181
4.2.6.2
Tín hiệu gọi dẫn đường Gatekeeper:
Các thông điệp chấp nhận được trao đổi giữa các điểm cuối và gatekeeper
trên các kênh RAS. Gatekeeper nhận các thông điệp tín hiệu gọi trên kênh tín hiệu gọi
từ một điểm cuối và truyền chúng đến điểm cuối khác trên kênh tín hiệu gọi của điểm
cuối khác đó.
4.2.6.3
Tín hiệu gọi trực tiếp:
Trong khi xác nhận việc thu nhận, gatekeeper xác định rằng các điểm cuối có
thể trao đổi các thông điệp call-signaling trực tiếp. Các điểm cuối trao đổi call-
signaling trên kênh call-signaling.
4.2.6.4
Tín hiệu điều khiển H.245:
Tín hiệu điều khiển H.245 gồm sự trao đổi của các thông điệp H.245 cuối-
nối-cuối giữa các điểm cuối H.323 giao tiếp. Các thông điệp điều khiển H.245 được
truyền trên các kênh điều khiển H.245. Kênh điều khiển H.245 là kênh logic 0 và được
mở hoàn toàn, không giống các kênh truyền thông. Các thông điệp truyền gồm các
thông điệp trao đổi khả năng của các terminal, các thông điệp đóng và mở kênh logic.
4.2.6.5
Trao đổi khả năng:
Trao đổi khả năng là một tiến trình dùng các thông điệp trao đổi của các
terminal giao tiếp để cung cấp các khả năng truyền nhận của chúng đối với các điểm
cuối tương ứng. Khả năng truyền miêu tả khả năng của terminal để truyền dòng truyền
thông. Khả năng nhận miêu tả khả năng của terminal để nhận và xử lý các dòng truyền
thông đến.
4.2.6.6
Tín hiệu kênh luận lý:
Một kênh logic mang thông tin từ một điểm cuối đến một điểm cuối khác
(trong trường hợp hội thảo điểm-nối-điểm) hay nhiều điểm cuối (trong trường hợp hội
182
thảo điểm-nối-nhiều điểm). H.245 cung cấp các thông điệp để mở hay đóng một kênh
logic; một kênh giao tiếp chỉ có một hướng.
4.2.7 Tín hiệu gọi H.225 và tín hiệu điều khiển H.245:
Ví dụ mạng đơn giản chứa hai thiết bị đầu cuối H.323( T1 và T2)kết nối với
gatekeeper. Giả sử dùng tín hiệu gọi trực tiếp. Cũng giả sử rằng dòng truyền sử dụng
kiểu đóng gói RTP. Hình dưới mô tả cách thức thiết lập cuộc gọi H.323
Hình 4-5 Thiết lập cuộc gọi H323
1. T1 gởi thông điệp RAS ARQ trên kênh RAS đến gatekeeper để đăng ký. T1
đòi hỏi sử dụng tín hiệu gọi trực tiếp.
2. Gatekeeper các nhận lại quyền của T1 bằng cách gởi ACF đến T1.
Gatekeeper chỉ đỉnh trong ACF là T1 có thể sử dụng tín hiệu gọi trực tiếp.
183
3. T1 gởi thông điệp thiết lập tín hiệu gọi H.225 đến T2 yêu cầu kết nối.
4. T2 hồi đáp lại với một thông điệp xử lý cuộc gọi H.225 đến T1
5. Bây giờ T2 phải đăng ký với gatekeeper. Nó gởi thông điệp RAS ARQ đến
gatekeeper trên kênh RAS.
6. Gatekeeper xác nhận đăng ký bằng cách gởi thông điệp RAS ARQ đến T2
7. T2 thông báo cho T2 về việc thiết lập kết nối bằng cách hởi thông điệp cảnh
báo H.225
8. Sau đó T2 xác nhận lại việc thiết lập kết nối bằng cách gợi thông điệp kết nối
đến T1, và cuộc gọi được thực hiện.
Dòng tín hiệu điều khiển H.323
184
9. Kênh điều khiển H.225 được thiết lập giữa T1 và T2. T1 gởi một thông điệp
H.245 TerminalCapbabilitySet đến T2 để trao đổi khả năng của nó.
10. T2 báo nhận những khả năng của T1 bằng cách gởi thông điệp H.245
Terminal CapabilitySetAck
11. T2 trao đổi khả năng của nó với T1 bằng cách gởi thông điệp H.245
TerminalCapabititySet
12. T1 báo nhận những khả năng của T2 bằng cách gởi thông điệp H.245
Terminal CapabilitySetAck
thông điệp H.245
13. T1 mở kênh
truyền với T2 bằng cách gởi
openLogicalChannel. Địa chỉ vận chuyển của kêng RTCP được bao gồm trong
thông điệp.
14. T2 báo nhận sự thiết lập kênh luận lý một chiều từ T1 đến T2 bằng cách gởi
thông điệp H.245 openLogicalChannelAck. Bao gồm trong thông điệp báo nhận
là địa chỉ vận chuyển của RTP cung cấp nởi T2 để cho T1 sử dụng cho việc gởi
dòng truyền thông RTP và địa chỉ RTCP nhận từ T1 sớm hơn
15. Sau đó T2 mở kênh truyền với T1 bằng cách gởi thông điệp H.245
openLogicalChannel. Địa chỉ vận chuyển của kênh RTCP được bao gồm trong
thông điệp
16. T2 báo nhận sự thiết lập của kênh luận lý một chiều từ T2 đến T1 bằng cách
gởi thông điệp H.245 openLogicalChannelAck. Bao gồm trong thông điệp báo
nhận là địa chỉ vận chuyển của RTP cung cấp bởi T1 để cho T2 sử dụng cho
việc gởi dòng truyền thông RTP và địa chỉ RTCP nhận từ T2 sớm hơn.
Bây giờ giao tiếp dòng hai chiều được thiết lập
185
Hình 4-6 H.323 Media Stream and Media Control Flows
17. T1 gởi dòng truyền thông đóng gói theo RTP đến T2
18. T2 gởi dòng truyền thông đóng gói theo RTP đến T1
19. T1 gởi thông điệp RTCP đến T2
20. T2 gởi thông điệp RTCP đến T1
186
Hình 4-7 Giải phóng cuộc gọi
21. T2 bắt đầu giải phóng cuộc gọi. Nó gởi thông điệp kết thúc phiên làm việc
đến T1.
22. T1 giải phóng điểm cuối ở cuộc gọi và xác nhận sự giải phóng bằng cách
gởi thông điệp kết thúc phiên làm việc đến T2.
23. T2 hoàn thành việc giải phóng cuộc gọi bằng cách gởi thông điệp giải phóng
hoàn toàn H.225 đến T1
24. T1 và T2 thoát ra khỏi gatekeeper bằng cách gởi thông điệp RAS DRQ đến
gatekeeper
25. Gatekeeper cũng thoát ra khỏi T1 và T2 và xác nhận bằng cách gởi thông
điệp DCF đến T1 và T2
187
4.2.8 Nghiên cứu thư viện Objective Open H.323 for C
4.2.8.1 Kiến trúc :
Objective Open H.323 for C được xem là một ứng dụng đơn giản, một tiến
trình. Nó cho phép một điểm cuối H.323 đơn lẻ được thiết lập kết nối thông qua kêng
truyền và tín hiệu H.323. Trộn tín hiệu vào ra được thực hiện bằng lệnh Select hay Poll
của Unix để theo dõi tất cả các kênh vào ra đang hoạt động. Giao tiếp TCP/IP và UDP
được hỗ trợ.
Chương trình ứng dụng với ngăn xếp được thực hiện thông qua các hàm
quay lui. Ngăn xếp được thiết kế theo hướng sự kiện và sẽ hồi đáp lại dòng vào ra hay
theo sự kiện thời gian bởi các hàm quay lui đã đăng ký được gọi lại. Những hàm quay
lui được định nghĩa bởi nhiều loại thông điệp Q.931/H.225 khác nhau.
Thôngđiệp Q.931/H.225
Hàm quay lui
Mô tả
Xảy ra khi thông điệp setup
được nhận, hay nếu RAS
được bật lên, khi
gatekeeper chấp nhận yêu
Setup
onIncomingCall
cầu thiết lập cuộc gọi
Hàm quay lui này được gọi
thông sau khi thông điệp
Setup
onOutcomingCall
thiết lập Q.931 được gởi
Xảy ra khi thông điệp cảnh
Alert
onAlerting
giác Q.931 được nhận
Xảy ra khi thông điệp kết
nối Q.931 được nhận. Nó
không xảy ra cho tới sau
khi thông đệp tạo đường đi
H.245 trong thông điệp kết
nối được xử lý
Connect
onCallEstablished
Facility
Xử lý bên trong. Thông
188
điệp H.245 tạo đường ống
hay yêu cầu bắt đầu H.245
được xử lý
Xảy ra khi thông điệp giải
phóng hoàng toàn Q.931
ReleaseComplete
onCallClear
được nhận
Information
Notify
Progress
Status
Không có hành động nào
Status Enquiry
được thực hiện trên các
SetupAck
thông điệp này
Chương trình ứng dụng H.323 sử dụng giao tiếp đồng đẳng cho việc trao đổi
dữ liệu. Điều này có nghĩa là bất cứ ứng dụng nào cũng đóng hai vai trò vừa là client,
vừa là server. Đây là ứng dụng gọi điện đơn giản dựa trên H.323 mô tả khả năng thiết
lập cuộc gọi, thương lưởng về khả năng và bắt đầu kênh truyền âm thanh.
4.2.8.2 Mẫu thiết kế ứng dụng H.323 đơn giản:
4.2.8.2.1 Khởi tạo điểm cuối:
Trước khi ngăn xếp ooh323c có thể làm mọi việc, cấu trúc điểm cuối phải
được khởi tạo. Nó được thu65c hiện bằng cách gọi các hàm sau:
ooH323EpInitialize(args…)
Tham số bao gồm thông tin về định danh người gọi, loại cuộc gọi được thực
hiện( âm thanh, hình ảnh, hay fax) và tên tập tin lưu vết đường đi, chỗ mà thông tin bản
ghi được lưu trữ.
Những thuộc tính khác có thể được thiết lập thông qua một loạt các cuộc
gọi hàm ooH323EpSet. Những thuộc tính được thiết lập này trong đối tượng điểm cuối
toàn cục. Ví dụ:
189
ooH323EpSetAliasH323ID : có thể được sử dụng để thiết lập định
danh trong địa chỉ bí danh.
Việc sử dụng dịch vụ client gatekeeper RAS – “Registration,
Admission, and Status” nên được khởi tạo thông qua việc gọi hàm sau :
ooGkClientInit(eGkMode, szGkAddr, iGkPort)
Đối với những cuộc gọi điểm nối điểm đơn giản, thông số chế độ
gatekeeper nên được thiết lập là RasNoGatekeeper và tất cả các thông số nên được
thiết lập là 0. Các chế độ Gatekeeper khác là RasDiscoverGatekeeper( khám phá một
gatekeeper) hay là RasUseSpecificGatekeeper( sử dụng gatekeeper xác định). Các
thông số khác được sử dụng để thiết lập địa chỉ Ip và số Port
4.2.8.2.2
Thêm vào khả năng:
Một ứng dụng H.323 phải xác định cho máy khách của nó biết nó có khả
năng làm cái gì. Thương lượng về khả năng sẽ được diễn ra bên trong việc xử ý thông
điệp H.245 để đạt đến sự đồng ý lẫn nhau dựa trên tập các khả năng.
Những khả năng được xác định dựa trên một loạt các hàm sau đây:
ooAddCapability(capability, type, callbacks);
giá trị tham số capabitity được định nghĩa trong ooCapability.h. Đây là
những hằng số định nghĩa lọai khả năng đã biết. Người sử dụng có thể ở rộng danh
sách này nếu muốn chương trình hỗ trợ những khả năng không có trong danh sách.
Tham số type xác định lọai khả năng được định nghĩa trong
MULTIMEDIA_SYSTEM_CONTROL.h
Có nhiều loại hàm quay lui khác nhau được thực hiện khi kênh luận lý
được mở hay đóng. Những hàm quay lui được xác định ở đây:
startReceiveChannel
startTransmitChannel
stopReceiveChannel
190
stopTransmitChannel
4.2.8.2.3 Định nghĩa hàm quay lui:
Khi các điểm cuối được thiết lập, người dùng đăng ký các hàm quay lui mà họ
định nghĩa. Hàm quay lui được định nghĩa ở cả mức độ H.245 khi kênh luận lý được
mở hay đóng hay ở mức độ Q.931/H.225 khi những thông điệp tín hiệu được trao đổi.
Ngăn xếp sẽ thực thi những hàm này khi sự kiện gắn với hàm quay lui đó xảy ra.
Các hàm quay lui Q.931/H.225 được đăng ký bằng cách gọi những hàm sau:
ooH323EpRegisterCallbacks
Ít nhất thì người dùng phải thực thi những hàm quay lui khả năng để bắt đầu
và kết thúc dòng truyền cho ứng dụng đặc biết của họ. Bắt đầu hay kết thúc dòng
truyền không được hỗ trợ trong ooH323c
4.2.8.2.4 Tạo H.323 Listener:
Một H.323 Listener được tạo để chấp nhận các yêu cầu kết nối vào. Tất cả mọi
thứ để bắt đầu listener là gọi hàm sau:
ooCreateH.323Listener();
4.2.8.2.5 Khởi tạo cuộc gọi:
Dùng để mở kênh truyền cho bất cứ loại giao tiếp truyền thông nào – không
chỉ là âm thanh. Một cuộc gọi được khởi tạo để gởi hình ảnh hay dữ liệu. Hàm
ooMakeCall (dest, callToken, bufsiz) được sử dụng cho mục đích này.
4.2.8.2.6 Đóng một cuộc gọi:
Mỗi bên kết nối đều có thể đóng cuộc gọi. Gọi hàm :
ooHangCall(callToken)
4.2.8.2.7 Đóng ngăn xếp:
191
Gọi hàm ooStopMonitor để đóng ngăn xếp. Nó sẽ gọi
làm hàm
ooMonitorChannel thoát. Khi điều này xảy ra, người dùng sẽ gọi hàm ooH323Destroy
ở cuối chương trình dọn dẹp điểm cuối
4.3
Windows Media Encoder
4.3.1 Windows Media Encoder:
Windows Media Encoder SDK (Software Developement Kit) là một trong
những thành phần chính của Microsoft Windows Media 9 Series. Những phần khác
gồm:
• Microsoft Windows Media Services 9 Series SDK
• Microsoft Windows Media Format 9 Series SDK
• Microsoft Windows Media Rights Manager 9 Series SDK
• Microsoft Windows Media Player 9 Series SDK
• Windows Media 9 Series Embedded Product Adaptation Kit (PAK)
Windows Media Encoder SDK được thiết kế cho những ai muốn phát triển một
ứng dụng Windows Media Encoder bằng cách dùng các hàm API (application
proramming interface – giao diện lập trình ứng dụng) tự động hóa cao. Với SDK này,
một lập trình viên dùng C++, Microsoft Visual Basic, hay một ngôn ngữ dạng kịch bản
có thể bắt các nội dung đa truyền thông và mã hóa và các tập tin hay dòng (stream)
dạng Windows Media. Chẳng hạn, bạn có thể dùng API tự động hóa này để :
o Broadcast content trực tuyến: một tổ chức truyền tin có thể dùng API tự động
hóa để lên lịch chụp tự động và broadcast nội dung. Các ngành vận chuyển địa
phương có thể dẫn dòng các ảnh động của điều kiện đường ở những điểm gây
nguy hiểm, cảnh báo tài xế về tình trạng kẹt xe và khuyến cáo dùng những con
đường khác.
192
o Batch-process nội dung : một tổ chức sản xuất truyền thông phải xử lý một số
lượng lớn các tập tin, có thể cần tạo tiến trình chạy nền dùng API tự động hóa
để bắt mã hóa dòng lặp đi lặp lại, cái này sau cái khác. Một tập đoàn có thể
dùng API tự động hóa để xử lý các dịch vụ truyền thông theo dòng với ngôn
ngữ kịch bản hay dùng và Windows Script Host. Windows Script Host là máy
chủ độc lập ngôn ngữ có thể dùng để chạy bất kỳ các engine kịch bản trên
Windows 95 hay sau đó, Windows NT, hay Windows 2000.
o Tạo giao diện người dùng tùy biến : một nhà cung cấp dịch vụ Internet có thể
xây dựng một giao diện dùng chức năng của API tự động hóa để chụp, mã hóa,
và broadcast dòng truyền thông. Thay vào đó, ta có thể dùng các giao diện định
nghĩa trước dành cho người dùng trong API tự động hóa với cùng mục đích.
o Quản trị từ xa các ứng dụng Windows Media Encoder: ta có thể dùng API
tự động hóa để chạy, sửa lỗi và quản trị các ứng dụng Windows Media Encoder
từ máy ở xa.
Tài liệu này cung cấp cái nhìn tổng quan về các đề tài mã hóa chung, hướng dẫn
lập trình, và các tham chiếu đầy đủ về các giao diện, đối tượng, kiểu liệt kê, cấu trúc và
hằng, đi kèm là các ví dụ.
4.3.1.1 Tìm hiểu Windows Media Encoder SDK :
Windows Media Encoder SDK mạnh mẽ và đáng tin cậy, cung cấp một tập
phong phú về giao diện cho phép các lập trình viên tích hợp Windows Media vào trong
các ứng dụng và dòng công việc. Windows Media Encoder SDK hỗ trợ nhiều ngôn ngữ
lập trình gồm C++, Visual Basic, Visual Basic Scripting Edition (VBScript), Visual
Basic cho ứng dụng, và tất cả các ngôn ngữ lập trình thuộc bộ Microsoft .NET. Nhiều
ứng dụng khác nhau có thể phát triển dùng Windows Media Encoder SDK, chẳng hạn
video e-mail, các thu thập giám sát bảo mật, bộ mã hóa dạng nền, công cụ chụp màn
hình, các add-ins Microsoft PowerPoint® and Microsoft Office, các bộ thâu số, các
193
ứng dụng mã hóa tùy biến. Chẳng hạn, phần mềm Windows Media Encoder phát triển
dựa trên Windows Media Encoder SDK.
Windows Media Encoder SDK cung cấp một tập các tính năng rộng lớn, cho
phép người dùng thực hiện:
o Mã hóa nhiều định dạng tập tin khác nhau.
o Xem dữ liệu đầu vào và đầu ra của nội dung trong khi xử lý mã hóa.
o Mã hóa nội dung theo dòng hay theo tập tin. Các dòng có thể kéo từ các ứng
dụng mã hóa hay đẩy lên một server Windows Media.
o Điều khiển các thiết bị số dùng chính các ứng dụng mã hóa.
o Nhận các số liệu thống kê trong quá trình hay sau quá trình mã hóa.
o Tạo và hiệu chỉnh các profile mã hóa tùy biến.
o Chỉnh sửa các dòng bằng cách tạo nhiều tập tin từ một tập tin multiple bit rate
(MBR) đơn, hay bằng cách tạo một tập tin MBR từ nhiều tập tin.
o Chỉnh sửa tập tin Windows Media bằng cách cắt bớt các khỏang bắt đầu và kết
thúc, hay bằng các thêm các dữ liệu meta, kịch bản, đánh dấu, và chỉ mục.
o Bảo vệ nội dung trong suốt quá trình mã hóa dùng công nghệ quản lý chữ ký
số (digital rights management DRM).
Windows Media Encoder SDK xây dựng trên Windows Media Format SDK,
cung cấp các chức năng cấp thấp. Không như Windows Media Format SDK, Windows
Media Encoder SDK hỗ trợ các ngôn ngữ kịch bản và cho phép xây dựng các ứng dụng
phức tạp với rất ít mã thêm vào. Hơn nữa, Windows Media Encoder SDK hỗ trợ nhiều
nguồn dữ liệu và tùy chọn xuất mà không cần người lập trình tự viết các thành phần
cấp thấp này.
4.3.1.2 Tìm hiểu Windows Media Format :
Windows Media Format là một định dạng thuộc chủ quyền cho dẫn dòng âm
thanh, hình ảnh và văn bản từ server Internet đến máy khách. Một tập tin Windows
194
Media có thể lưu trữ và trình diễn cục bộ. Mỗi tập tin Windows Media chứa một hay
nhiều dòng truyền thông để tạo nên một trình diễn đa truyền thông. Phân phối dòng
đồng bộ với dòng thời gian. Các danh sách sau giới thiệu các tính năng chính của
Windows Media Format:
o Một tập tin Windows Media Encoder có thể truyền bằng bất kỳ nghi thức vận
chuyển liên lạc dữ liệu bên dưới. Windows Media Format không chỉ rõ định
dạng về các gói tin dữ liệu cho các nghi thức mạng khác nhau.
o Windows Media Format linh động về băng thông. Một dòng đầu vào đơn có thể
mã hóa thành nhiều dòng đầu ra trong một tập tin Windows Media. Mỗi dòng
tùy biến lại như thế khác nhau ở chỗ tần số bit mà nó có thể dựng hình, và chỉ
một tại một thời điểm. Server Windows Media dùng phân dùng thông minh để
gởi dòng chất lượng cao đến một máy khách phù hợp.
o Phân phối và trình diễn nhiều dòng dữ liệu truyền thông đồng bộ với dòng thời
gian chung. Dữ liệu truyền thông trong một tập tin Windows Media đóng tem
thời gian.
o Một tập tin Windows Media có thể chứa một dòng hình ảnh, một dòng âm
thanh, một dòng Web, và một dòng kịch bản.
o Máy khách không cần lưu trữ nôi dung dựa trên Windows Media để trình diễn
dòng đa truyền thông.
o Windows Media Format xây dựng các điều khiển cấp thấp các thao tác đọc và
viết.
4.3.1.3 So sánh WME SDK và WMF SDK:
Functionality
Windows Media
Windows Media
Encoder SDK
Format SDK
Tự động hóa ứng dụng.
Có
Không
195
Tự động đọc nội dung truyền thông nén
Có
Không
và thô, và nén ghi như nội dung dựa trên
Windows Media.
Có thể chuyển các dòng âm thanh hình
Có
Không
ảnh sang định dạng Windows Media.
Cung cấp giao diện người dùng Windows
Có
Không
Media Encoder tùy chọn.
Cài đặt Profile Manager.
Có
Không
Có thể điều khiển từ xa các ứng dụng
Có
Không
Windows Media Encoder.
Nén dữ liệu đa truyền thông.
Có
Có
Chỉnh sửa thông tin header của tập tin
Có
Có
Windows Media.
Ghi các số liệu thống kê mã hóa.
Có
Có
Giải nén dữ liệu đa truyền thông để chơi
Không
Có
lại.
Lập trình tạo một profile.
Có
Có
Điều khiển thiết bị số bằng lập trình.
Có
Không
Tích hợp thẳng với các dịch vụ tạo nội
Có
Không
dung DRM.
Hỗ trợ ngôn ngữ lập trình.
C,
C++,
C#, C, C++
196
Microsoft Visual
Basic,
Visual
Basic
Scripting Edition,
Microsoft JScript®,
Microsoft Windows
Script Host
Bảng 4-2 So sánh Windows Media Encoder SDK và Windows Media Format
4.3.2 Hệ thống cấp bậc các đối tượng mã hóa:
Windows Media Encoder SDK được xây dựng trên nền Windows Media
Format, một API cấp thấp chứa các giao diện cần cho:
o Ghi các tập tin Windows Media từ các dữ liệu âm thanh, hình ảnh, và kịch bản
chưa nén.
o Đọc và giải nén các tập tin Windows Media.
o Chỉnh sửa thông tin header tập tin Windows Media.
Windows Media Encoder SDK bao gồm một số đối tượng có thể tạo thể hiện
độc lập bằng cách dùng class ID của chúng. Chẳng hạn, tạo đối tượng WMEncoder để
lấy con trỏ tới một giao diện IWMEncoder. Các con trỏ đến các giao diện khác, tuy
nhiên, phải được lấy thông qua những đối tượng khác đã có sẵn. Chẳng hạn, để nhận
giao diện IWMEncBroadcast, ta phải dùng phương thức get_Broadcast trong giao
diện IWMEncoder vì ta không thể dùng CoCreateInstance()để nhận trực tiếp giao
diện IWMEncBroadcast. Sơ đồ sau mô tả quan hệ các đối tượng trong Windows
Media Encoder SDK và những đối tượng nào phụ thuộc đối tượng khác.
197
Hình 4-8 Cấp bậc đối tượng trong Windows Media Encoder SDK
198
Ví dụ C++
// Initialize the COM library.
HRESULT hr = Coinitialize(NULL);
// Create a WMEncoder object and retrieve an
// IWMEncoder interface pointer.
IWMEncoder* pEncoder = NULL;
HRESULT hr = CoCreateInstance( CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder
(void**) (&pEncoder));
// Create a broadcast interface.
IWMEncBroadcast* pBrdCst = NULL;
hr = pEncoder->get_Broadcast(&pBrdCst);
4.3.2.1 Đóng gói đối tượng:
Các đối tượng và thư viện kiểu Windows Media Encoder SDK được tổ chức
thành các thư viện liên kết động và các tập tin thực thi.
Tên
Mô tả
Mspshell.dll
Chứa giao diện IMSPropShell dùng để tạo các máy chủ chứa
các trang tính năng dùng chung. Windows Media Encoder dùng
IMSPropShell cài đặt các trang tính năng định nghĩa trước của
giao diện người dùng Session Properties.
Streameditor.dll
Chứa giao diện IWMEncStreamEdit dùng để cắt và nối các
199
dòng trong tập tin Windows Media.
Wmdevctl.dll
Chứa các giao diện cần cho điều khiển các thiết bị số và dùng
danh sách quyết định chỉnh sửa (edit decision list EDL).
Wmedque.dll
Chứa bộ lọc hàng đợi bản ghi.
Wmenceng.dll
Chứa các giao diện cần cho cấu hình và thao tác xử lý mã hóa.
Wmencloc.dll
Chứa các giao diện cần cho quản trị các ứng dụng Windows
Media Encoder trên máy tính ở xa.
Wmesrcwp.dll
Chứa bộ bao mã nguồn.
WMEncRes.dll
Chứa các chuỗi tài nguyên của Windows Media Encoder.
Wmex.dll
Chứa các thành phần giao diện người dùng và giao diện
IWMEncProfileManager. Các lớp này là các trang tính năng
định nghĩa sẵn được điều khiển MSPropShell ActiveX dùng
để tạo giao diện người dùng Session Properties.
Wmexfmwp.dll
Chứa bộ bao plug-in chuyển đổi.
Wmexres.dll
Chứa các chuỗi tài nguyên cho các trang tính năng.
Wmprevu.dll
Chứa giao diện IWMEncDataview dùng cho tạo các nội dung
truyền thông xem trước và trong lúc mã hóa.
Wmsservertypelib.dll Chứa thư viện kiểu mô hình đối tượng server, được dùng để lấy
các số liệu thống kê server và họat động với DCOM.
Wmenc.exe
Chạy Windows Media Encoder và trình bày giao diện người
dùng, chứa đối
tượng WMEncoderApp và giao diện
200
IWMEncoderApp.
Wmencagt.exe
Chứa đối tượng WMEncoderAgent dùng để quản trị các ứng
dụng Windows Media Encoder trên máy ở xa.
Bảng 4-3 Các tập tin thư viện liên kết động và thực thi
4.3.2.2 Các tính năng:
4.3.2.2.1 Điều khiển các kết nối đến máy khách:
Điều khiển truy cập đến máy tính đang chạy các ứng dụng Windows Media
Encoder. Một cách để broadcast một dòng là cho phép các máy khách kết nối trực tiếp
máy đang chạy ứng dụng Windows Media Encoder (tính năng kéo). Mặc định, tối đa 5
máy có thể kết nối. Các quản trị viên có thể thay đổi giới hạn này lên cực đại là 50
bằng
cách
chỉnh
trong
khóa
registry
HKEY_CLASSES_ROOT\Software\Microsoft\Windows
Media
Tools\Encoder\MaxClientConnections. Bởi vì mỗi kết nối hao tốn tài nguyên hệ
thống và mạng, cần xem xét lại khả năng máy và môi trường truyền. Quá nhiều kết nối
có thể làm quá tải máy và ngăn cản các máy khách chính đáng kết nối vào.
Ta có thể ngăn cấm máy kết nối bằng cách áp mặt na địa chỉ IP để kết nối máy
khách. Mặc định, bất kỳ máy khách chưa đến giới hạn kết nối đều được cho phép. Mặc
dù Windows Media Encoder SDK không cung cấp sẵn API để làm việc này, ta có thể
dùng Windows Media Format. Để biết thêm thông tin, xem thêm giao diện
IWMAddressAccess và IWMAddressAccess2 trong trợ giúp của Windows Media
Format.
4.3.2.2.2 Dùng DCOM:
Distributed Component Object Model (DCOM – mô hình đối tượng thành phần
phân phối) là một nghi thức cho phép các thành phần phần mềm liên lạc trực tiếp thông
201
qua mạng dùng TCP/IP. DCOM có thể dùng với Windows Media Encoder khi ta đang
quản trị từ xa các máy đang chạy ứng dụng Windows Media Encoder, và trên các
server Windows Media khi ta dùng tính năng đẩy.
4.3.2.3 Tìm hiểu codec:
Nội dung âm thanh và hình ảnh có thể tiêu tốn nhiều băng thông dẫn dòng và
tạo tập tin lớn. Bằng cách nén lại, nó có thể broadcast trên những băng thông Internet
phổ biến và lưu thành tập tin Windows Media với kích thước vừa phải. Ta có thể nén
nội dung bằng cách áp dụng các thuật toán nén cho dữ liệu, dựa vào chất lượng đầu ra
mong muốn và băng thông khả dụng. Trước khi nội dung được trình diễn, nội dung
được giải nén bằng các thuật tóan giải nén.
Những thuật toán nén và giải nén như thế gọi là các codec. Bảng sau cung cấp
thông tin về các codec khả dụng trong Windows Media Encoder Series.
Codec
Description
Windows
Media
Tạo âm thanh full surround trên những máy tính cài đặt card âm
Audio 9 Professional
thanh đa kênh và Windows XP. Cung cấp nội dung âm thanh
trong Windows Media Format để chơi lại trên thiết bị xem như
đầu đĩa DVD hay hộp set-top.
Windows
Media
Cung cấp mã hóa toàn vẹn về âm thanh.
Audio 9 Lossless
Windows
Media
Cung cấp chất lượng âm thanh không gì sánh kịp cho dẫn dòng
Audio 9
băng hẹp Internet và âm nhạc download hi-fi. Hỗ trợ mã hóa
VBR. Tương thíc hòan tòan với mọi phiên bản Windows Media
Player.
Windows
Media Cung cấp chất lượng tốt cho nội dung âm thanh với tiếng nói.
202
Audio 9 Voice
Windows
Media
Tăng cường chất lượng hình ảnh cho người dùng Internet băng
Video 9
rộng và phân phối phim hình gần như DVD với tốc độ lên đến
400 Kbps. Cho phép chơi lại chất lượng sắc nét hơn bằng cách
kết hợp nội dung trên TV và hộp set-top.
Windows
Media
Hỗ trợ nhiều loại băng thông mạng. Giảm việc trùng lắp nội
Video 8.1
dung trước khi mã hóa.
Windows
Media
Cho phép người dùng Windows Media Player 7 xem các nội
Video 7
dung phim hình đã mã hóa mà không cần phải download về bộ
codec mới nhất. Lựa chọn tốt nhất cho những máy tính không
thể hỗ trợ những yêu cầu trình diễn của các codec mới nhất.
Windows
Media
Cung cấp cải thiện xử lý các hình bóng, chuyển động trên màn
Video 9 Screen
hình, và cuộn cho chụp màn hình. Hỗ trợ CBR và VBR một
bước mã hóa mà không rớt khung. Codec này thì tối ưu hóa
hòan toàn cho cả kịch bản dẫn dòng và download.
Bảng 4-4 Các codec
4.3.2.4 Các yêu cầu về tính năng:
Các tính năng.
Feature
Windows Media Player
Operating
Codec
system
6.4 7.1/Windows® XP 9
Series
203
Interlaced output
X
Microsoft
Windows Media
Windows XP
Video 9
video
X
Nonsquare pixel
output
X
Multiple-
resolution MBR
content
X
DRM support
X X
X
Multichannel
Microsoft
Windows Media
audio
Windows XP
Audio
9
Professional
X
Microsoft
Windows Media
High-resolution
Windows XP
Audio
9
audio (24-bit, 96
Professional
kHz)
Dynamic
range
X
Microsoft
Windows Media
control
Windows XP
Audio
9
Professional
X X
X
See
the
CBR
encoding
following
(one- or
two-
table.
pass)
Quality
based
X
X
See
the
VBR
following
table.
204
Bit
rate-based
X
X
See
the
VBR
following
table.
Peak bit
rate-
X
X
See
the
based VBR
following
table.
Bảng 4-5 Các tính năng
Bảng tiếp theo này ghi những phương thức mã hóa cho các codec.
Quality
Bit
rate-
Peak bit rate-
Two-
Codec
One-
based VBR
based VBR
based VBR
pass
pass
CBR
CBR
Windows Media
Có
Có
Có
Có
Có
Audio
9
Professional
Windows Media
Không
Không
Có
Không
Không
Audio
9
Lossless
Windows Media
Có
Có
Có
Có
Có
Audio 9
Windows Media
Có
Không
Không
Không
Không
Audio 9 Voice
Windows Media Có
Có
Có
Có
Có
205
Video 9
Windows Media
Có
Có
Có
Có
Có
Video 8.1
Windows Media
Có
Có
Có
Có
Có
Video 7
Windows Media
Có
Không
Có
Không
Không
Video 9 Screen
Bảng 4-6 Các phương thức mã hóa hỗ trợ
4.3.2.5 Phần mở rộng của tập tin:
Phần mở rộng của tập tin cung cấp thông tin về nội dung chứa trong tập tin:
o Các ứng dụng tạo ra các tập tin Windows Media chứa dòng âm thanh, dòng kịch
bản hay cả hai phải dùng phần mở rộng .wma.
o Các ứng dụng tạo ra các tập tin Windows Media chứa cả dòng hình ảnh, dòng
âm thanh phải dùng phần mở rộng .wmv. Các tập tin này cũng chứa dòng kịch
bản.
o Tập tin chứa cấu hình Windows Media Encoder định nghĩa trước phải dùng
phần mở rộng .wme.
o Profile dùng phần mở rộng .prx.
Chú ý:
Ta có thể dùng phần mở rộng .asf đổi chỗ qua lại với .wmv và .wma, tuy nhiên,
.wmv và .wma xác định loại nội dung.
4.3.2.6 Lập trình bằng C++:
Chủ đề này nói những lưu ý về lập trình trong C++. Nếu không nói rõ, các ví dụ
về sau sử dụng Microsoft Visual C++® 6.0. Từ đây trở đi, tuy ta chú trọng vào lập
206
trình bằng C++. C++ khá linh động trong viết mã nhưng bù lại, thảo chương khá dài và
yêu cầu cẩn thận cao hơn so với VB và C#.
Khi lập trình trong C++, ta phải theo các tập tin tiêu đề cần thiết vào project:
Tập tin tiêu đề Mô tả
localagent.h
Các giao diện cho phép quản trị từ xa với các ứng dụng Windows
Media Encoder.
mspropshell.h Các giao diện cho phép cài đặt các hộp thoại chứa các trang tính
năng định nghĩa sẵn.
wmdevctl.h
Các giao diện cho điều khiển thiết bị số.
wmdrmprf.h
Các giao diện cho bảo vệ nội dung với DRM.
wmencode.h
Các giao diện dùng để cấu hình và chạy các ứng dụng Windows
Media Encoder.
wmencvu.h
Giao diện được dùng để tạo và chạy phần xem trước của dòng.
wmsencid.h
Một tập hòan chỉnh các định nghĩa DISPID.
Bảng 4-7 Các tập tin tiêu đề
Thay vì thêm các tập tin tiêu đề wmencode.h và mspropshell.h, ta có thể sử
dụng các thư viện phát sinh các lớp bao để đơn giản hóa các giao diện COM liên quan:
#import "WMEnc.exe"
#import "MSPShell.dll"
4.3.2.7 Tạo ứng dụng mã hóa:
Để tạo một ứng dụng mã hóa, ta thường trải qua các bước sau:
207
1. Tạo một đối tượng Encoder.
2. Tạo một nhóm nguồn để giữ các dòng đa truyền thông ta muốn mã hóa, và sau
đó thêm các dòng đa truyền thông (chẳng hạn, một tập tin hay dữ liệu đầu vào
từ card chụp màn hình) vào nhóm nguồn.
3. Chọn profile mã hóa. Một profile cho biết loại codec nào được dùng để mã hóa
nội dung và xác định số lượng và tốc độ bit của dòng xuất.
4. Xác định nhu cầu muốn broadcast nội dung đã mã hóa thành dòng, lưu vào tập
tin, hay cả hai.
5. Tùy chọn, ta cũng có thể:
o Thêm thông tin mô tả (như tựa và bản quyền) và các thuộc tính tùy biến.
o Xử lý trước phim hình, chẳng hạn lọc và xén lại, hay xác định các thiết lập
tối ưu hóa.
o Thêm họa tiết.
o Bảo vệ nội dung bằng cách mật mã hóa với DRM.
6. Khởi động mã hóa.
4.3.2.7.1 Tạo đối tượng Encoder:
Tùy thuộc vào ta tạo giao diện người dùng (UI) như thế nào:
o Khi dùng UI tùy biến, tạo một đối tượng WMEncoder trực tiếp bằng cách dùng
giao diện IWMEncoder trong C++.
o Khi thể hiện các thành phần UI định nghĩa sẵn từ Windows Media Encoder, lấy
đối tượng WMEncoder từ WMEncoderApp hay IWMEncoderApp. Đối
tượng WMEncoderApp phải có phạm vi module tồn tại bên ngoài thủ tục.
4.3.2.7.2 Tạo đối tượng WMEncoder với giao diện tùy biến:
Ví dụ C++
// Include libraries.
#include
208
#include "wmencode.h"
// Declare variables.
HRESULT hr = S_OK;
IWMEncoder* pEncoder = NULL;
// Initialize the COM library and retrieve a pointer
// to an IWMEncoder interface.
hr = CoInitialize(NULL);
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance(CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder,
(void**) &pEncoder;
}
// Release pointers.
if ( pEncoder )
{
pEncoder->Release();
pEncoder = NULL;
}
4.3.2.7.3 Tạo đối tượng WMEncoder khi hiển thị giao diện người
dùng ứng dụng định nghĩa sẵn:
209
Ví dụ C++
// Include libraries.
#include
#include "wmencode.h"
// Declare variables.
HRESULT hr;
IWMEncoder* pEncoder;
IWMEncoderApp* pEncoderApp;
// Initialize the COM library and retrieve a pointer
// to an IWMEncoderApp interface.
hr = CoInitialize(NULL);
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance( CLSID_WMEncoderApp,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IWMEncoderApp,
(void**) &pEncoderApp);
}
// Display the user interface.
if ( SUCCEEDED( hr ) )
{
hr = pEncoderApp->put_Visible(VARIANT_TRUE);
}
// Acquire an IWMEncoder interface.
if ( SUCCEEDED( hr ) )
210
{
hr = pEncoderApp->get_Encoder(&pEncoder);
}
// Release pointers.
if ( pEncoder )
{
pEncoder->Release();
pEncoder = NULL;
}
if ( pEncoderApp )
{
pEncoderApp->Release();
pEncoderApp = NULL;
}
4.3.2.7.4 Thao tác trên các nguồn và nhóm nguồn:
Windows Media Encoder SDK dùng khái niêm “nguồn” và “nhóm nguồn” để
xác định các dòng nhập ta muốn mã hóa:
o Một nguồn là một dòng âm thanh, dòng hình ảnh, dòng HTML, hay dòng kịch
bản.
o Một nhóm nguồn là một sưu tập các nguồn bao gồm tổ hợp bất kỳ của một
nguồn âm thanh, một nguồn hình ảnh, một nguồn HTML, và một nguồn kịch
bản.
Chẳng hạn, để mã hóa một buổi hòa nhạc sống, ta sẽ thiết lập một nhóm nguồn
gồm một nguồn âm thanh và một nguồn hình ảnh. Để mã hóa trình diễn PowerPoint, ta
211
phải thiết lập một nhóm nguồn gồm một nguồn âm thanh, một nguồn hình ảnh và một
nguồn HTML.
Ta có thể thiết lập nhiều nhóm nguồn trong một session mã hóa để mã hóa đồng
thời các nội dung khác nhau. Chẳng hạn, để broadcast một buổi họp công ty trực tuyến,
ta sẽ thiết lập bốn nhóm nguồn tương ứng với sự kiện chính, phim hình chào mừng,
phim hình lúc ngừng, và phim hình lúc bế mạc.
Hình 4-9 Mô tả 4 nhóm nguồn
Chỉ một nhóm nguồn có thể họat động tại một thời điểm; ta có thể hoặc đặt một
nhóm nguồn hoạt động, hay có các nhóm nguồn xoay dần theo thứ tự khi cái đầu tiên
kết thúc mã hóa.
Xác định các nguồn cho một session mã hóa theo các bước sau:
1. Tạo một
sưu
tập nhóm nguồn để giữ các nhóm nguồn dùng
IWMEncSourceGroupCollection.
2. Tạo một nhóm nguồn để giữ một hay nhiều nguồn đầu vào dùng
IWMEncSourceGroup.
212
3. Tạo các đối tượng cho các nguồn đầu vào và thêm chúng vào nhóm nguồn dùng
IWMEncSource.
4. Dùng IWMEncSource, cho biết loại nguồn đầu vào. Nếu nguồn là một thiết bị
(chẳng hạn là card bắt hình hay máy quay phim DV), trước hết ta phải liệt kê số
nguồn
khả
dụng
trên
hệ
thống
dùng
IWMEncPluginInfo,
IWMEncSourcePluginInfoManager,
và
IWMEncDeviceControlPluginInfoManager.
Ở đây, ta sẽ xem xét kỹ chủ đề : “Dùng chụp màn hình như là nguồn”, cho biết
làm cách nào dùng chụp màn hình như một nguồn hình ảnh.
Dùng chụp màn hình như một nguồn
Ta có thể dùng chụp màn hình như một nguồn hình ảnh. Plug-in chụp màn hình
cho phép bắt hình ở mọi phần của màn hình, chẳng hạn, để bắt di chuyển của mouse để
mô tả một quá trình. Ta cũng có thể chụp từ một card nối đến thiết bị chuyển đổi quét.
Ta cần cấu hình plug-in để xác định khu vực ta muốn chụp. Một cách là dùng
giao diện IPropertyBag (xem ví dụ C++ ở dưới).
Cân nhắc các tham khảo sau để cải thiện việc chụp màn hình:
o Dùng Windows Media Video 9 codec.
o Dùng card đồ họa nhanh hơn.
o Dùng máy tính cấu hình mạnh hay máy tính với bộ đôi vi xử lý.
o Vô hiệu hóa tăng tốc phần cứng. Từ Control Panel Display Properties, và tab
Settings, click Advanced. Trên tab Troubleshoot, kéo slide thiết lập tăng tốc
phần cứng về None.
o Giảm chất lượng màu để giảm số lượng dữ liệu mà card đồ họa cần xử lý. Từ
Control Panel Display Properties, trên tab Settings, click thiết lập thấp hơn cho
Color quality.
o Chạy ứng dụng mã hóa trong 256 màu. Right-click tập tin thực thi, chọn
Properties, và trên tab Compatibility, chọn Run in 256 colors.
213
o Chỉnh sửa profile để giảm tốc độ khung và kích thước bắt ảnh. Tăng cường tần
suất bit cũng cho kết quả tốt hơn.
o Đóng hết những ứng dụng không cần thiết.
o Bỏ ảnh nền.
Ví dụ Visual Basic sau mô tả việc dùng chụp màn hình như là một nguồn. Ví dụ
C++ mô tả cấu hình chụp màn hình dùng property bag.
Ví dụ C++
// Include libraries.
#include
#include
#include
#include "C:\WMSDK\WMEncSDK9\include\wmencode.h"
// Define the screen capture properties.
#define WMSCRNCAP_CAPTUREWINDOW CComBSTR("CaptureWindow")
#define WMSCRNCAP_WINDOWLEFT CComBSTR("Left")
#define WMSCRNCAP_WINDOWTOP CComBSTR("Top")
#define WMSCRNCAP_WINDOWRIGHT CComBSTR("Right")
#define WMSCRNCAP_WINDOWBOTTOM CComBSTR("Bottom")
#define WMSCRNCAP_FLASHRECT CComBSTR("FlashRect")
#define WMSCRNCAP_ENTIRESCREEN CComBSTR("Screen")
#define WMSCRNCAP_WINDOWTITLE CComBSTR("WindowTitle")
// Declare variables.
HRESULT hr = S_OK;
IWMEncoder* pEncoder;
IWMEncSourceGroupCollection* pSrcGrpColl;
214
IWMEncSourceGroup* pSrcGrp;
IWMEncSource* pSrc;
IWMEncVideoSource2* pSrcVid;
IPropertyBag* pPropertyBag;
CComVariant varValue;
// Initialize the COM library and retrieve a pointer to an IWMEncoder interface.
hr = CoInitialize(NULL);
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance(CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder,
(void**) &pEncoder);
}
// Retrieve the source group collection.
if ( SUCCEEDED( hr ) )
{
hr = pEncoder->get_SourceGroupCollection(&pSrcGrpColl);
}
// Add a source group to the collection.
if ( SUCCEEDED( hr ) )
{
hr = pSrcGrpColl->Add(CComBSTR("SG_1"), &pSrcGrp);
215
}
if ( SUCCEEDED( hr ) )
{
hr = pSrcGrp->AddSource(WMENC_VIDEO, &pSrc);
}
// Retrieve an IWMEncVideoSource2 pointer.
if ( SUCCEEDED( hr ) )
{
hr = pSrc->QueryInterface(IID_IWMEncVideoSource2, (void**)&pSrcVid);
}
// Add a video source to the source group.
if ( SUCCEEDED( hr ) )
{
hr = pSrcVid->SetInput(CComBSTR("ScreenCap://ScreenCapture1"));
}
// Retrieve a pointer to the property bag.
if ( SUCCEEDED( hr ) )
{
hr = pSrcVid->QueryInterface(IID_IPropertyBag, (void**)&pPropertyBag);
}
// Set full screen capture.
{
varValue = true;
216
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_ENTIRESCREEN, &varValue );
}
}
// Set the capture area.
{
// nLeft, nRight, nTop, and nBottom are the dimensions to capture
int nLeft, nRight, nTop, nBottom;
// Initialize the capture area. The size must be even.
varValue = false;
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_ENTIRESCREEN, &varValue );
}
varValue = nLeft;
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_WINDOWLEFT, &varValue );
}
varValue = nRight;
if ( SUCCEEDED( hr ) )
{
217
hr = pPropertyBag->Write( WMSCRNCAP_WINDOWRIGHT, &varValue );
}
varValue = nTop;
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_WINDOWTOP, &varValue );
}
varValue = nBottom;
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_WINDOWBOTTOM, &varValue );
}
varValue = true;
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_FLASHRECT, &varValue );
}
// Continue configuring the encoding session.
// Release pointers.
if ( pSrcGrpColl )
{
pSrcGrpColl->Release();
218
pSrcGrpColl = NULL;
}
if ( pSrcGrp )
{
pSrcGrp->Release();
pSrcGrp = NULL;
}
if ( pSrcVid )
{
pSrcVid->Release();
pSrcVid = NULL;
}
if ( pSrc )
{
pSrc->Release();
pSrc = NULL;
}
if ( pPropertyBag )
{
pPropertyBag->Release();
pPropertyBag = NULL;
}
if ( pEncoder )
{
pEncoder->Release();
pEncoder = NULL;
}
219
}
4.3.2.7.5 Thao tác với profile :
Một profile xác định codec nào được dùng để nén và quyết định số lượng dòng
xuất và tần suất bit của chúng. Mỗi profile nhắm đến các người dùng và mục đích khác
nhau. Chẳng hạn, một profile có thể với chất lượng dựa trên variable bit rate (VBR)
cho download tập tin, trong khi profile khác dùng constant bit rate (CBR) để tạo dòng.
Mỗi profile được dùng cho một số xác định và loại các dòng nguồn. Chỉ có một profile
có thể liên quan đến mỗi nhóm nguồn tại một thời điểm. và mọi nhóm nguồn phải dùng
cùng profile trong sessiion mã hóa.
Ta có thể dùng profile tùy biến (các tập tin .prx ) hay các profile hệ thống đi
kèm với Windows Media Encoder SDK. Dành cho các ứng dụng mã hóa mới, ta nên
tạo và dùng các profile tùy biến để đáp ứng nhu cầu của người dùng. Các profile hệ
thống không cập nhật cho các codec mới và không hỗ trợ tương thích ngược.
4.3.2.7.6 Thêm thông tin phụ:
o Thông tin hiển thị: thông tin sẽ xuất hiện trong trình chơi nhạc, bao gồm tên
tác giả và tên nghệ sĩ, tựa bài, mô tả, xếp loại, và bản quyền. Dùng
IWMEncDisplayInfo để thêm thông tin này.
o Thuộc tính của người dùng: thông tin này thêm vào form có từng cặp tên-giá
trị mà ta định nghĩa, cho phép ta thêm vào các thông tin thêm về session mã
hóa. Chẳng hạn, ta có thể thêm ngày và thể loại vào bằng cách dùng
IWMEncAttributes.
Ví dụ thêm thuộc tính tùy biến vào trong một tập tin truyền thông.
Ví dụ C++
#include
#include
#include
220
#include "wmencode.h"
// Declare variables.
HRESULT hr;
IWMEncoder* pEncoder;
IWMEncAttributes* pAttr;
CComBSTR m_bstrName;
CComVariant m_varValue;
CComVariant m_varIndex;
CComVariant m_varRemove;
long cnt;
// Initialize the COM library and retrieve a pointer
// to an IWMEncoder interface.
hr = CoInitialize( NULL );
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance(CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder,
(void**) &pEncoder);
}
// Retrieve a pointer to an IWMEncAttributes interface.
if ( SUCCEEDED( hr ) )
221
{
hr = pEncoder->get_Attributes( &pAttr );
}
// Add name-value pairs to the attributes collection.
_bstr_t bName[] =
{
_bstr_t("Date Created: "),
_bstr_t("Time Created: "),
_bstr_t("File Content: ")
}
_variant_t vVal[] =
{
_variant_t("02/15/2000"),
_variant_t("13:30:15"),
_variant_t("multimedia data"),
}
for( int i = 0; i < 3 && SUCCEEDED(hr); i++ )
{
hr = pAttr->Add(bName[i],vVal[i]);
}
// Retrieve the name-value pairs from the collection.
if ( SUCCEEDED( hr ) )
{
hr = pAttr->get_Count(&cnt);
222
}
for ( i = 0; i < cnt && SUCCEEDED( hr ); i++ )
{
hr = pAttr->Item(i, &m_bstrName, &m_varValue);
}
// Remove an attribute by name.
if ( SUCCEEDED( hr ) )
{
m_varRemove = "File Content: ";
hr = pAttr->Remove(m_varRemove);
}
// Remove an attribute by index.
if ( SUCCEEDED( hr ) )
{
m_varRemove = 0;
hr = pAttr->Remove(m_varRemove);
}
// Remove all attributes.
if ( SUCCEEDED( hr ) )
{
hr = pAttr->RemoveAll();
}
223
// Release pointers.
if ( pAttr )
{
pAttr->Release();
pAttr = NULL;
}
if ( pEncoder )
{
pEncoder->Release();
pEncoder = NULL;
}
4.3.2.7.7 Tiền xử lý âm thanh và hình ảnh:
Cho phép thực hiện việc lọc khung, xén hình, và tạo họa tiết cho dữ liệu đầu ra.
Ta không đi sâu vào các chi tiết phức tạp của phần này.
4.3.2.7.8 Xác định dữ liệu đầu ra:
4.3.2.7.8.1 Lưu nội dung mã hóa xuống tập tin:
Ta có thể lưu nội dung của một tập tin Windows Media, hoặc song song với ứng
dụng broadcast hoặc chỉ riêng lưu tập tin. Ta có thể hạn chế kích thước tập tin xuất khi
lưu, hoặc bằng khỏang xử lý dài nhất hay kích thước tập tin lớn nhất.
Ta cũng có thể xác định nhóm nguồn nào cần lưu trữ. Chẳng hạn, nếu ta mã hóa
một màn hình chào mừng tĩnh, một buổi trình diễn sống và một màn hình kết thúc tĩnh,
ta có thể chỉ muốn lưu trữ buổi trình diễn sống. Mặc định, các nhóm nguồn tự động lưu
trữ, vì vậy đặt thuộc tính AutoArchive trong IWMEncSourceGroup.AutoArchive để
Dừng hẳn hoặc Ngưng các nhóm nguồn ta không muốn lưu.
224
Để điều khiển bằng tay việc khởi động, dừng, ngưng quá trình xử lý lưu, đặt
phương thức Archive dùng IWMEncoder hay WMEncoder. Mặc định, việc lưu trữ
bắt đầu ngay khi mã hóa bắt đầu. Nếu muốn điều khiển bằng tay, đặt thuộc tính
EnableAutoArchive bằng false.
Ví dụ mô tả việc lưu nội dung mã hóa xuống tập tin bằng IWMEncFile2.
Ví dụ C++
// Include libraries.
#include
#include "wmencode.h"
// Declare variables.
HRESULT hr;
IWMEncoder* pEncoder;
IWMEncFile* pFile;
// Initialize the COM library and retrieve a pointer
// to an IWMEncoder interface.
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance( CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder,
(void**) &pEncoder);
}
// Specify a file in which to save encoded content.
225
if ( SUCCEEDED( hr ) )
{
hr = pEncoder->get_File(&pFile);
}
if ( SUCCEEDED( hr ) )
{
hr = pFile->put_LocalFileName(CComBSTR("C:\\filename.wmv"));
}
// Release pointers.
if ( pFile )
{
pFile->Release();
pFile = NULL;
}
if ( pEncoder )
{
pEncoder->Release();
pEncoder = NULL;
}
4.3.2.7.8.2 Đẩy một dòng lên Windows Media Server
Ta có thể broadcast một dòng bằng cách đẩy nó lên một Windows Media
Server, rất hữu ích khi ta muốn khởi tạo kết nối từ một ứng dụng mã hóa.
Khi đẩy một dòng lên một Windows Media Server, ta cần biết :
o Tên của Windows Media Server. Tên này có thể là alias, một fully qualified
domain name, hay địa chỉ IP.
226
o Tên của điểm xuất bản mới hay có sẵn.
o Tùy chọn, tên điểm xuất bản cho cấu hình thiết lập.
Đây là phần liên quan đến phiên bản Windows hỗ trợ Windows Media Server,
ta không đi sâu vào phần này.
4.3.2.7.8.3
Broadcast một dòng từ ứng dụng Windows Media
Encoder:
Broadcast một dòng bằng cách cho phép những máy khách (Windows Media
Server, Web Server, hay player) để kết nối trực tiếp với máy chạy ứng dụng Windows
Media Encoder để kéo dòng về.
Máy khách kết nối với dòng bằng cách dùng http://Địa chỉ:cổng cho kết nối
Internet hay http://tên_máy_mã_hóa:cổng cho kết nối LAN. Ta có thể ngăn cấm truy
cập theo mặt nạ IP.
Để broadcast một dòng từ máy chủ, dùng IWMEncBroadcast để xác định nghi
thức và số hiệu cổng để có thể broadcast.
Ví dụ C++
// Include libraries.
#include
#include "wmencode.h"
// Declare variables.
HRESULT hr;
IWMEncoder* pEncoder;
IWMEncBroadcast* pBrdcst;
// Initialize the COM library and retrieve a pointer
// to an IWMEncoder interface.
227
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance( CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder,
(void**) &pEncoder);
}
// Specify a broadcast protocol and port number.
if ( SUCCEEDED( hr ) )
{
hr = pEncoder->get_Broadcast(&pBrdcst);
}
if ( SUCCEEDED( hr ) )
{
hr = pBrdcst->put_PortNumber(WMENC_PROTOCOL_HTTP, 8080);
}
// Release pointers.
if ( pBrdcst )
{
pBrdcst->Release();
pBrdcst = NULL;
}
if ( pEncoder )
{
228
pEncoder->Release();
pEncoder = NULL;
}
4.3.2.8 Quản trị từ xa ứng dụng mã hóa:
Quản trị viên có thể điều khiển nhiều thể hiện các ứng dụng Windows Media
Encoder trên máy ở xa hoặc bằng LAN hay Internet. Bằng cách dùng các giao diện
IWMEncAgentLocator, IWMEncoderAgent và IWMEncoderNamesCollection, ta
có thể viết các ứng dụng cho phép :
o Tạo các đối tượng WMEncoderApp trên các máy ở xa.
o Liệt kê các đối tượng WMEncoder trên máy cho trước.
o Kết nối và điều khiển một đối tượng WMEncoder.
o Quan sát trạng thái của quá trình xử lý mã hóa.
Windows Media Encoder phải cài sẵn trên máy ở xa, và ta phải dùng tiện ích
cấu hình DCOM để thiết lập việc khởi phát, truy cập, và cho phép cấu hình cho cả
Windows Media Encoder và Windows Media Encoder Agent. Để tạo các đối tượng
WMEncoderApp, đối tượng WMEncoderAgent phải chạy trên máy ở xa. Ta có thể
khởi động đối tượng WMEncoderAgent bằng tay hay tự động.
4.3.2.9 Phụ chú:
Các phần ta không đi sâu, để biết rõ hơn có thể xem ở tài liệu Windows Media
Encoder SDK Documentation đi kèm với bộ SDK.
Chương 5 Tổng kết
5.1 Kết luận:
5.1.1 Kết quả đạt được:
Sau khi thực hiện đề tài, chúng em thu được một số kết quả sau:
229
• Tìm hiểu được công nghệ truyền hình ảnh âm thanh trên mạng LAN và Internet
H323. Đây là một công nghệ mã nguồn mở đa nền, rất hữu ích trong việc viết
các ứng dụng chạy trên nhiều hệ điều hành khác nhau.
• Tìm hiểu được bộ phát triển phần mềm Microsoft Windows Media Encoder.
Với khả năng tích hợp chặt chẽ với hệ điều hành Windows, Windows Media
Encoder SDK rất thích hợp cho tìm hiểu các khái niệm về mã hóa, giải mã các
dòng âm thanh, hình ảnh trên hệ điều ảnh Windows.
• Tìm hiểu được nghi thức RFB, một nghi thức đơn giản nhằm giao tiếp điều
khiển máy tính từ xa. Chúng em cũng thu lượm được các kiến thức về vùng đệm
khung dành cho màn hình, khả năng xây dựng tối ưu hóa cách viết mã từ mã
nguồn mở của nghi thức.
• Tìm hiểu được các kỹ thuật kiểm sóat hệ thống một cách triệt để, khả năng lập
trình tương tác cấp thấp với bộ nhớ, thiết bị, tùy biến giao diện trên cũng như
các cơ chế quản lý hệ thống của hệ điều hành Windows.
• Xây dựng thành công một chương trình điều khiển máy tính từ xa, đồng thời
qua đó, nắm được khả năng tích hợp và sử dụng được các đồ án mã nguồn mở
do cộng đồng công nghệ thông tin thế giới cung cấp không vụ lợi.
5.1.2 Hạn chế:
Mặc dù chúng em đã cố gắng hết sức nhưng ứng dụng vẫn còn một số hạn
chế nhất định:
• Ứng dụng vẫn chưa kiểm tra được tính ổn định cao trên nhiều máy.
• Chưa tối ưu hóa trong việc truyền gởi dữ liệu giữa chương trình điều khiển và
chương trình bị điều khiển.
• Ứng dụng có thể chiếm dụng bộ nhớ khi thực hiện việc quan sát màn hình máy
khách.
230
5.2 Hướng phát triển
Với những kết quả đạt được và những hạn chế nêu trên, đề tài có thể mở rộng
theo các hướng sau:
• Mở rộng khả năng kiểm soát : không những hệ thống máy khách mà cả nội dung
người dùng lướt web bằng các cách như lọc liên kết, nội dung trang web.
• Mở rộng thêm các loại hình phục vụ : như nhắn tin điện thoại di động…
• Cải thiện độ ổn định và vấn đề bộ nhớ cho chương trình.
231
TÀI LIỆU THAM KHẢO
Tài liệu viết :
Tài liệu trong nước
[1] Nguyễn Tri Tuấn, Cơ sở lý thuyết về lập trình sự kiện và hook (chặn các thông
điệp), môn học Lập trình C trên Windows, 24/2/2004.
[2] Nguyễn Tri Tuấn, Thư viện liên kết động, môn học Lập trình C trên Windows,
24/2/2004.
Tài liệu nước ngoài
[3] Robert Kuster, Three Ways to Inject Your Code into Another Process,
www.codeproject.com, 25/7/2003 cập nhật 21/8/2003.
[4] António Feijão, Lock Windows Desktop, www.codeproject.com, 14/6/2004 cập
nhật 9/12/2004.
[5] Fad B, Using GINA.DLL to Spy on Windows User Name & Password And to
Disable SAS (Ctrl+Alt+Del), www.codeproject.com, 22/8/2003.
[6] =[ Abin ]=, An All-Purpose Keyboard Hooker, www.codeproject.com,
13/5/2004 cập nhật 31/5/2004.
[7] Microsoft Development Network (MSDN), tài liệu các loại, Microsoft Visual
Studion 6.0, 10/2003.
[8]
Joseph M. Newcomer, Hook and DLLs, www.codeproject.com, 1/4/2001.
[9] Derek Lakin, CTabCtrlSSL - An easy to use, flexible extended tab control,
www.codeproject.com, 21/9/2001.
[10] dang!, Ownerdraw Tab Controls - Borders and All, www.codeproject.com,
31/1/2002 cập nhật 1/7/2002.
[11] Barry, Barry's Screen Capture, www.codeguru.com, 4/2/2003.
232
[12] P.GopalaKrishna, Various methods for capturing the screen, 24/8/2003.
[13] Carlos Antollini, A set of ADO Classes - version 2.04, www.codeproject.com,
25/4/2001 cập nhật 3/8/2002.
[14] Tristan Richardson, The RFB Protocol version 3.8, RealVNC Ltd, 8/3/2005.
[15] Davide Calabro, CButtonST v3.9 (MFC Flat buttons), www.codeproject.com,
25/11/1999 cập nhật 29/3/2003.
[16] Nischant S, Tile, center and stretch a bitmap as your MFC dialog background,
www.codeproject.com, 7/6/2002.
[17] PJ Naughter, Splasher v1.32
- A Splash Screen
Implementation,
www.codeproject.com, 4/3/2000.
[18] Mark Jackson, Sort List Control, www.codeproject.com, 7/9/2001.
[19] Chris Maunder, Adding Icons to the System Tray, www.codeproject.com,
30/11/1999 cập nhật 3/8/2003.
Websites :
[20] Codeproject, http://www.codeproject.com.
[21] RealVNC Ltd, http://www.realvnc.com.
[22] H323, http://www.openh323.org.
[23] Vox Gratia, http://www.voxgratia.org.
[24] Microsoft Corporation, http://www.microsoft.com.
[25] Codeguru, http://www.codeguru.com.
[26] Source Forge, http://www.sourceforge.net.
233