Skip to content

Commit 12a4be9

Browse files
author
Etienne Stalmans
committed
extensions to mapi library for interacting with attachments
1 parent e1c8d51 commit 12a4be9

File tree

8 files changed

+721
-50
lines changed

8 files changed

+721
-50
lines changed

mapi/constants.go

+29
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const (
7777
PtypBinary = 0x0102
7878
PtypMultipleBinary = 0x1102
7979
PtypTime = 0x0040
80+
PtypObject = 0x000D
8081
)
8182

8283
//Folder id/locations -- https://msdn.microsoft.com/en-us/library/office/cc815825.aspx
@@ -549,3 +550,31 @@ var PidTagBodyHTML = PropertyTag{PtypBinary, 0x1013}
549550

550551
//PidTagHTMLBody is the same as above?
551552
var PidTagHTMLBody = PropertyTag{PtypString, 0x1013}
553+
554+
var PidTagAttachMethod = PropertyTag{PtypInteger32, 0x3705}
555+
556+
var PidTagRenderingPosition = PropertyTag{PtypInteger32, 0x370B}
557+
558+
var PidTagAttachContentId = PropertyTag{PtypString, 0x03712}
559+
560+
var PidTagAttachMimeTag = PropertyTag{PtypString, 0x370E}
561+
562+
var PidTagAttachmentLinkId = PropertyTag{PtypInteger32, 0x7FFA}
563+
564+
var PidTagAttachFlags = PropertyTag{PtypInteger32, 0x3714}
565+
566+
var PidTagAttachmentHidden = PropertyTag{PtypBoolean, 0x7FFE}
567+
568+
var PidTagAttachLongFilename = PropertyTag{PtypString, 0x3707}
569+
570+
var PidTagAttachFilename = PropertyTag{PtypString, 0x3704}
571+
572+
var PidTagAttachExtension = PropertyTag{PtypString, 0x3703}
573+
574+
var PidTagMessageAttachments = PropertyTag{PtypObject, 0x0E13}
575+
576+
var PidTagAttachPathName = PropertyTag{PtypString, 0x3708}
577+
var PidTagAttachLongPathName = PropertyTag{PtypString, 0x370D}
578+
var PidTagAttachPayloadProviderGuidString = PropertyTag{PtypString, 0x3719}
579+
var PidTagTrustSender = PropertyTag{PtypInteger32, 0x0E79}
580+
var PidTagAttachDataBinary = PropertyTag{PtypBinary, 0x3701}

mapi/datastructs.go

+244-44
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,39 @@ type RopSaveChangesMessageResponse struct {
410410
MessageID []byte
411411
}
412412

413+
//RopGetAttachmentTableRequest to open the attachment table
414+
type RopGetAttachmentTableRequest struct {
415+
RopID uint8 //0x21
416+
LogonID uint8
417+
InputHandleIndex uint8
418+
OutputHandleIndex uint8
419+
TableFlags uint8
420+
}
421+
422+
//RopGetAttachmentTableResponse struct holding the attachment table index
423+
type RopGetAttachmentTableResponse struct {
424+
RopID uint8 //0x21
425+
OutputHandleIndex uint8
426+
ReturnValue uint32
427+
}
428+
429+
//RopOpenAttachmentRequest to open an existing attachment
430+
type RopOpenAttachmentRequest struct {
431+
RopID uint8 //0x22
432+
LogonID uint8
433+
InputHandleIndex uint8
434+
OutputHandleIndex uint8
435+
OpenAttachmentFlags uint8
436+
AttachmentID uint32
437+
}
438+
439+
//RopOpenAttachmentResponse struct holding the attachment index
440+
type RopOpenAttachmentResponse struct {
441+
RopID uint8 //0x22
442+
OutputHandleIndex uint8
443+
ReturnValue uint32
444+
}
445+
413446
//RopSynchronizationOpenCollectorRequest struct used to open handle to new email message
414447
type RopSynchronizationOpenCollectorRequest struct {
415448
RopID uint8
@@ -455,34 +488,34 @@ type RopOpenMessageResponse struct {
455488

456489
//RopCreateAttachmentRequest used to create an attachment
457490
type RopCreateAttachmentRequest struct {
458-
RopID uint8 //0x23
459-
LogonID uint8
460-
InputHandle uint8
461-
OutputHandle uint8
491+
RopID uint8 //0x23
492+
LogonID uint8
493+
InputHandleIndex uint8
494+
OutputHandleIndex uint8
462495
}
463496

464497
//RopCreateAttachmentResponse holds the response to a create attachment
465498
type RopCreateAttachmentResponse struct {
466-
RopID uint8 //0x23
467-
OutputHandle uint8
468-
ReturnValue uint32
469-
AttachmentID []byte
499+
RopID uint8 //0x23
500+
OutputHandleIndex uint8
501+
ReturnValue uint32
502+
AttachmentID uint32
470503
}
471504

472505
//RopSaveChangesAttachmentRequest used to create an attachment
473506
type RopSaveChangesAttachmentRequest struct {
474-
RopID uint8 //0x25
475-
LogonID uint8
476-
InputHandle uint8
477-
OutputHandle uint8
478-
SaveFlags uint8
507+
RopID uint8 //0x25
508+
LogonID uint8
509+
InputHandleIndex uint8
510+
ResponseHandleIndex uint8
511+
SaveFlags uint8
479512
}
480513

481514
//RopSaveChangesAttachmentResponse holds the response to a create attachment
482515
type RopSaveChangesAttachmentResponse struct {
483-
RopID uint8 //0x23
484-
OutputHandle uint8
485-
ReturnValue uint32
516+
RopID uint8 //0x25
517+
ResponseHandleIndex uint8
518+
ReturnValue uint32
486519
}
487520

488521
//RopFastTransferSourceCopyToRequest struct used to open handle to message
@@ -543,52 +576,66 @@ type RopFastTransferSourceGetBufferResponse struct {
543576

544577
//RopOpenStreamRequest struct used to open a stream
545578
type RopOpenStreamRequest struct {
546-
RopID uint8 //0x2B
547-
LogonID uint8
548-
InputHandle uint8
549-
OutputHandle uint8
550-
PropertyTag []byte
551-
OpenModeFlags byte
579+
RopID uint8 //0x2B
580+
LogonID uint8
581+
InputHandleIndex uint8
582+
OutputHandleIndex uint8
583+
PropertyTag PropertyTag
584+
OpenModeFlags uint8
552585
}
553586

554587
//RopOpenStreamResponse struct used to open a stream
555588
type RopOpenStreamResponse struct {
556-
RopID uint8 //0x2B
557-
OutputHandle uint8
558-
ReturnValue uint32
559-
StreamSize uint32
589+
RopID uint8 //0x2B
590+
OutputHandleIndex uint8
591+
ReturnValue uint32
592+
StreamSize uint32
560593
}
561594

562-
//RopWriteStreamRequest struct used to open a stream
595+
//RopWriteStreamRequest struct used to write a stream
563596
type RopWriteStreamRequest struct {
564-
RopID uint8 //0x2B
565-
LogonID uint8
566-
InputHandle uint8
567-
DataSize uint16
568-
Data []byte
597+
RopID uint8 //0x2B
598+
LogonID uint8
599+
InputHandleIndex uint8
600+
DataSize uint16
601+
Data []byte
569602
}
570603

571-
//RopWriteStreamResponse struct used to open a stream
604+
//RopWriteStreamResponse struct used to write a stream
572605
type RopWriteStreamResponse struct {
573-
RopID uint8 //0x2B
574-
OutputHandle uint8
575-
ReturnValue uint32
576-
WrittenSize uint16
606+
RopID uint8 //0x2B
607+
InputHandleIndex uint8
608+
ReturnValue uint32
609+
WrittenSize uint16
610+
}
611+
612+
//RopCommitStreamRequest struct used to commit a stream
613+
type RopCommitStreamRequest struct {
614+
RopID uint8 //0x2B
615+
LogonID uint8
616+
InputHandleIndex uint8
617+
}
618+
619+
//RopCommitStreamResponse struct used to commit a stream
620+
type RopCommitStreamResponse struct {
621+
RopID uint8 //0x2B
622+
InputHandleIndex uint8
623+
ReturnValue uint32
577624
}
578625

579626
//RopSetStreamSizeRequest struct used to open a stream
580627
type RopSetStreamSizeRequest struct {
581-
RopID uint8 //0x2F
582-
LogonID uint8
583-
InputHandle uint8
584-
StreamSize uint64
628+
RopID uint8 //0x2F
629+
LogonID uint8
630+
InputHandleIndex uint8
631+
StreamSize uint64
585632
}
586633

587634
//RopSetStreamSizeResponse struct used to open a stream
588635
type RopSetStreamSizeResponse struct {
589-
RopID uint8 //0x2B
590-
OutputHandle uint8
591-
ReturnValue uint32
636+
RopID uint8 //0x2B
637+
OutputHandleIndex uint8
638+
ReturnValue uint32
592639
}
593640

594641
//RopReadStreamRequest struct used to open a stream
@@ -991,6 +1038,21 @@ func (openStream RopOpenStreamRequest) Marshal() []byte {
9911038
return utils.BodyToBytes(openStream)
9921039
}
9931040

1041+
//Marshal turn RopOpenStreamRequest into Bytes
1042+
func (setStreamSize RopSetStreamSizeRequest) Marshal() []byte {
1043+
return utils.BodyToBytes(setStreamSize)
1044+
}
1045+
1046+
//Marshal turn RopOpenStreamRequest into Bytes
1047+
func (writeStream RopWriteStreamRequest) Marshal() []byte {
1048+
return utils.BodyToBytes(writeStream)
1049+
}
1050+
1051+
//Marshal turn RopOpenStreamRequest into Bytes
1052+
func (commitStream RopCommitStreamRequest) Marshal() []byte {
1053+
return utils.BodyToBytes(commitStream)
1054+
}
1055+
9941056
//Marshal turn RopReadStreamRequest into Bytes
9951057
func (readStream RopReadStreamRequest) Marshal() []byte {
9961058
return utils.BodyToBytes(readStream)
@@ -1021,6 +1083,26 @@ func (deleteFolder RopDeleteFolderRequest) Marshal() []byte {
10211083
return utils.BodyToBytes(deleteFolder)
10221084
}
10231085

1086+
//Marshal turn RopGetAttachmentTableRequest into Bytes
1087+
func (getAttachTable RopGetAttachmentTableRequest) Marshal() []byte {
1088+
return utils.BodyToBytes(getAttachTable)
1089+
}
1090+
1091+
//Marshal turn RopCreateAttachmentRequest into Bytes
1092+
func (createAttach RopCreateAttachmentRequest) Marshal() []byte {
1093+
return utils.BodyToBytes(createAttach)
1094+
}
1095+
1096+
//Marshal turn RopOpenAttachmentRequest into Bytes
1097+
func (getAttach RopOpenAttachmentRequest) Marshal() []byte {
1098+
return utils.BodyToBytes(getAttach)
1099+
}
1100+
1101+
//Marshal turn RopSaveChangesAttachmentRequest into Bytes
1102+
func (saveAttach RopSaveChangesAttachmentRequest) Marshal() []byte {
1103+
return utils.BodyToBytes(saveAttach)
1104+
}
1105+
10241106
//Unmarshal function to convert response into ConnectResponse struct
10251107
func (connResponse *ConnectResponse) Unmarshal(resp []byte) error {
10261108
pos := 0
@@ -1430,6 +1512,124 @@ func (ropOpenFolderResponse *RopOpenFolderResponse) Unmarshal(resp []byte) (int,
14301512
return pos, nil
14311513
}
14321514

1515+
//Unmarshal function to produce RopCreateMessageResponse struct
1516+
func (getAttachmentTable *RopGetAttachmentTableResponse) Unmarshal(resp []byte) (int, error) {
1517+
pos := 0
1518+
1519+
getAttachmentTable.RopID, pos = utils.ReadByte(pos, resp)
1520+
getAttachmentTable.OutputHandleIndex, pos = utils.ReadByte(pos, resp)
1521+
getAttachmentTable.ReturnValue, pos = utils.ReadUint32(pos, resp)
1522+
1523+
if getAttachmentTable.ReturnValue != 0 {
1524+
return pos, &ErrorCode{getAttachmentTable.ReturnValue}
1525+
}
1526+
return pos, nil
1527+
}
1528+
1529+
//Unmarshal function to produce RopCreateMessageResponse struct
1530+
func (createAttachment *RopCreateAttachmentResponse) Unmarshal(resp []byte) (int, error) {
1531+
pos := 0
1532+
1533+
createAttachment.RopID, pos = utils.ReadByte(pos, resp)
1534+
createAttachment.OutputHandleIndex, pos = utils.ReadByte(pos, resp)
1535+
createAttachment.ReturnValue, pos = utils.ReadUint32(pos, resp)
1536+
1537+
if createAttachment.ReturnValue != 0 {
1538+
return pos, &ErrorCode{createAttachment.ReturnValue}
1539+
}
1540+
createAttachment.AttachmentID, pos = utils.ReadUint32(pos, resp)
1541+
return pos, nil
1542+
}
1543+
1544+
//Unmarshal function to produce RopCreateMessageResponse struct
1545+
func (getAttachment *RopOpenAttachmentResponse) Unmarshal(resp []byte) (int, error) {
1546+
pos := 0
1547+
1548+
getAttachment.RopID, pos = utils.ReadByte(pos, resp)
1549+
getAttachment.OutputHandleIndex, pos = utils.ReadByte(pos, resp)
1550+
getAttachment.ReturnValue, pos = utils.ReadUint32(pos, resp)
1551+
1552+
if getAttachment.ReturnValue != 0 {
1553+
return pos, &ErrorCode{getAttachment.ReturnValue}
1554+
}
1555+
1556+
return pos, nil
1557+
}
1558+
1559+
//Unmarshal function to produce RopSaveChangesMessageResponse struct
1560+
func (saveAttachResponse *RopSaveChangesAttachmentResponse) Unmarshal(resp []byte) (int, error) {
1561+
pos := 0
1562+
1563+
saveAttachResponse.RopID, pos = utils.ReadByte(pos, resp)
1564+
saveAttachResponse.ResponseHandleIndex, pos = utils.ReadByte(pos, resp)
1565+
saveAttachResponse.ReturnValue, pos = utils.ReadUint32(pos, resp)
1566+
1567+
if saveAttachResponse.ReturnValue != 0 {
1568+
return pos, &ErrorCode{saveAttachResponse.ReturnValue}
1569+
}
1570+
return pos, nil
1571+
}
1572+
1573+
//Unmarshal function to produce RopOpenStreamResponse struct
1574+
func (openStreamResponse *RopOpenStreamResponse) Unmarshal(resp []byte) (int, error) {
1575+
pos := 0
1576+
1577+
openStreamResponse.RopID, pos = utils.ReadByte(pos, resp)
1578+
openStreamResponse.OutputHandleIndex, pos = utils.ReadByte(pos, resp)
1579+
openStreamResponse.ReturnValue, pos = utils.ReadUint32(pos, resp)
1580+
1581+
if openStreamResponse.ReturnValue != 0 {
1582+
return pos, &ErrorCode{openStreamResponse.ReturnValue}
1583+
}
1584+
openStreamResponse.StreamSize, pos = utils.ReadUint32(pos, resp)
1585+
return pos, nil
1586+
}
1587+
1588+
//Unmarshal function to produce RopOpenStreamResponse struct
1589+
func (setStreamSizeResponse *RopSetStreamSizeResponse) Unmarshal(resp []byte) (int, error) {
1590+
pos := 0
1591+
1592+
setStreamSizeResponse.RopID, pos = utils.ReadByte(pos, resp)
1593+
setStreamSizeResponse.OutputHandleIndex, pos = utils.ReadByte(pos, resp)
1594+
setStreamSizeResponse.ReturnValue, pos = utils.ReadUint32(pos, resp)
1595+
1596+
if setStreamSizeResponse.ReturnValue != 0 {
1597+
return pos, &ErrorCode{setStreamSizeResponse.ReturnValue}
1598+
}
1599+
return pos, nil
1600+
}
1601+
1602+
//Unmarshal function to produce RopOpenStreamResponse struct
1603+
func (writeStreamResponse *RopWriteStreamResponse) Unmarshal(resp []byte) (int, error) {
1604+
pos := 0
1605+
1606+
writeStreamResponse.RopID, pos = utils.ReadByte(pos, resp)
1607+
writeStreamResponse.InputHandleIndex, pos = utils.ReadByte(pos, resp)
1608+
writeStreamResponse.ReturnValue, pos = utils.ReadUint32(pos, resp)
1609+
1610+
if writeStreamResponse.ReturnValue != 0 {
1611+
return pos, &ErrorCode{writeStreamResponse.ReturnValue}
1612+
}
1613+
1614+
writeStreamResponse.WrittenSize, pos = utils.ReadUint16(pos, resp)
1615+
return pos, nil
1616+
}
1617+
1618+
//Unmarshal function to produce RopCommitStreamResponse struct
1619+
func (commitStreamResponse *RopCommitStreamResponse) Unmarshal(resp []byte) (int, error) {
1620+
pos := 0
1621+
1622+
commitStreamResponse.RopID, pos = utils.ReadByte(pos, resp)
1623+
commitStreamResponse.InputHandleIndex, pos = utils.ReadByte(pos, resp)
1624+
commitStreamResponse.ReturnValue, pos = utils.ReadUint32(pos, resp)
1625+
1626+
if commitStreamResponse.ReturnValue != 0 {
1627+
return pos, &ErrorCode{commitStreamResponse.ReturnValue}
1628+
}
1629+
1630+
return pos, nil
1631+
}
1632+
14331633
//Unmarshal func
14341634
func (ropGetHierarchyResponse *RopGetHierarchyTableResponse) Unmarshal(resp []byte) (int, error) {
14351635
pos := 0

0 commit comments

Comments
 (0)